Home > front end >  UIActivityViewController: Close button in share sheet becomes transparent
UIActivityViewController: Close button in share sheet becomes transparent

Time:12-06

When I use UIActivityViewController to share an image the close button becomes transparent. I can click on its frame button but it is invisible for the user. And you cannot click outside to close on the sheet.

let activityItemMetadata = LinkMetadataManager(qrImage: image)
let activityVC = UIActivityViewController(
                   activityItems: [activityItemMetadata],
                   applicationActivities: nil)
activityVC.completionWithItemsHandler = {(activityType: UIActivityType?, completed: Bool, returnedItems: [Any]?, error: Error?) in
}
            
activityVC.activityItemsConfiguration = [
    UIActivity.ActivityType.mail,
    UIActivity.ActivityType.copyToPasteboard,
    UIActivity.ActivityType.airDrop,
    UIActivity.ActivityType.message
] as? UIActivityItemsConfigurationReading
            
activityVC.isModalInPresentation = false
self.present(activityVC, animated: true)

(https://i.stack.imgur.com/nJoez.png)

Close button appear like this:

image

CodePudding user response:

Most of your UIActivityViewController code is wrong.

  1. You should not be creating a LinkMetadataManager from the image and then using it as the item you wish to share.
  2. You are trying to create an array of activities and setting those as the activity configuration. This is all wrong.

Your code should look more like the following:

let activityVC = UIActivityViewController(activityItems: [ image ], applicationActivities: nil)
activityVC.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
    if completed || activityType == nil {
        // activity view is being dismissed
    }
}
present(activityVC, animated: true)

If you have a need to exclude certain activities you can add a line like the following:

activityVC.excludedActivityTypes = [ .assignToContact ] // Optionally exclude specific activities

If you want a bit more control you make use of UIActivityItemsConfiguration. The following is an example:

let configuration = UIActivityItemsConfiguration(objects: [ image ])
configuration.perItemMetadataProvider = { (index, key) in
    switch key {
    case .linkPresentationMetadata:
        // Maybe make use of your LinkMetadataManager class here
        var info = LPLinkMetadata()
        info.title = "Some Title"
        return info
    default:
        return nil
    }
}
let activityVC = UIActivityViewController(activityItemsConfiguration: configuration)
activityVC.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
    if completed || activityType == nil {
        // activity view is being dismissed
    }
}
present(activityVC, animated: true)

CodePudding user response:

UIActivityViewController is being presented in a UIModalPresentationStyle.overFullScreen style, which hides the default close button.

To fix this issue, you can set the modalPresentationStyle property of the UIActivityViewController instance to UIModalPresentationStyle.popover before presenting it. This will display the UIActivityViewController in a popover with a visible close button, and allow the user to click outside the popover to dismiss it.

modify the modalPresentationStyle property:

let activityItemMetadata = LinkMetadataManager(qrImage: image)
let activityVC = UIActivityViewController(
                   activityItems: [activityItemMetadata],
                   applicationActivities: nil)

// Set the modalPresentationStyle property to UIModalPresentationStyle.popover.
activityVC.modalPresentationStyle = .popover

activityVC.completionWithItemsHandler = {(activityType: UIActivityType?, completed: Bool, returnedItems: [Any]?, error: Error?) in
}
            
activityVC.activityItemsConfiguration = [
    UIActivity.ActivityType.mail,
    UIActivity.ActivityType.copyToPasteboard,
    UIActivity.ActivityType.airDrop,
    UIActivity.ActivityType.message
] as? UIActivityItemsConfigurationReading
            
activityVC.isModalInPresentation = false
self.present(activityVC, animated: true)
  • Related