【问题标题】:How can you add icon to a share sheet in swift?如何快速将图标添加到共享表?
【发布时间】:2020-08-16 13:56:47
【问题描述】:

我在我的 iOS 应用程序中使用共享表。我想弄清楚当它打开时如何在它的左上角添加一个图标。我添加了一个照片示例来说明我的意思。

[我的意思的示例照片][1]

    @IBAction func shareButtonClicked(_ sender: Any) {

        //Set the default sharing message.
        let message = "Check out Num8r, Its so much fun!"
        let link = NSURL(string: "https://apps.apple.com/us/app/num8r/id1497392799")

        // Screenshot:
        UIGraphicsBeginImageContextWithOptions(self.view.frame.size, true, 0.0)
        self.view.drawHierarchy(in: self.view.frame, afterScreenUpdates: false)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        //Set the link, message, image to share.
        if let link = link, let img = img {
            let objectsToShare = [message,link,img] as [Any]
            let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
            activityVC.excludedActivityTypes = [UIActivity.ActivityType.airDrop, UIActivity.ActivityType.addToReadingList]
            self.present(activityVC, animated: true, completion: nil)
    }
}

【问题讨论】:

    标签: swift xcode ios-sharesheet


    【解决方案1】:

    此代码仅适用于 iOS 13 作为最低目标。我添加了一个代码示例以在 SwiftUI 视图中添加一个真实的共享按钮,以防其他人需要它。此代码也适用于 iPad。

    您可以使用此类LinkMetadataManager 并添加您选择的图像。非常重要的部分是您必须将图像放在项目目录中,而不是在 Assets.xcassets 文件夹中。否则,它将不起作用。

    一切就绪后,您将在 SwiftUI 视图中以这种方式使用按钮。

    struct ContentView: View {
        
      var body: some View {
        VStack {
          ShareButton()
        }
      }
    }
    

    该类将与 Apple Store 链接共享您的应用程序。你可以分享任何你想要的东西。您可以使用LPLinkMetadata 查看图像是如何添加的,因为它是您感兴趣的部分。

    import LinkPresentation
    
    /// Transform url to metadata to populate to user.
    final class LinkMetadataManager: NSObject,  UIActivityItemSource {
    
      var linkMetadata: LPLinkMetadata
    
      let appTitle = "Your application name"
      let appleStoreProductURL = "https://apps.apple.com/us/app/num8r/id1497392799" // The url of your app in Apple Store
      let iconImage = "appIcon" // The name of the image file in your directory
      let png = "png" // The extension of the image
    
      init(linkMetadata: LPLinkMetadata = LPLinkMetadata()) {
        self.linkMetadata = linkMetadata
      }
    }
    
    // MARK: - LinkMetadataManager Setup
    extension LinkMetadataManager {
      /// Creating metadata to be populated in the share sheet.
      func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
    
        guard let url = URL(string: appleStoreProductURL) else { return linkMetadata }
    
        linkMetadata.originalURL = url
        linkMetadata.url = linkMetadata.originalURL
        linkMetadata.title = appTitle
        linkMetadata.iconProvider = NSItemProvider(
          contentsOf: Bundle.main.url(forResource: iconImage, withExtension: png))
    
        return linkMetadata
      }
    
      /// Showing an empty string returns a share sheet with the minimum requirement.
      func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return String()
      }
    
      /// Sharing the application url.
      func activityViewController(_ activityViewController: UIActivityViewController,
                                  itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        return linkMetadata.url
      }
    }
    

    使用 View 的这个扩展来触发 SwiftUI 视图上的共享表。

    import SwiftUI
    
    //  MARK: View+ShareSheet
    extension View {
    
      /// Populate Apple share sheet to enable the user to share Apple Store link.
      func showAppShareSheet() {
        guard let source = UIApplication.shared.windows.first?.rootViewController else {
          return
        }
    
        let activityItemMetadata = LinkMetadataManager()
    
        let activityVC = UIActivityViewController(
          activityItems: [activityItemMetadata],
          applicationActivities: nil)
    
        if let popoverController = activityVC.popoverPresentationController {
          popoverController.sourceView = source.view
          popoverController.permittedArrowDirections = []
          popoverController.sourceRect = CGRect(x: source.view.bounds.midX,
                                                y: source.view.bounds.midY,
                                                width: .zero, height: .zero)
        }
        source.present(activityVC, animated: true)
      }
    }
    

    然后,创建一个 ShareButton 作为组件,以在您的任何 SwiftUI 视图中使用它。这就是 ContentView 中使用的内容。

    import SwiftUI
    
    /// Share button to send app store link using the 
    /// Apple classic share screen for iPhone and iPad.
    struct ShareButton: View {
    
      @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    
      var body: some View {
        ZStack {
          Button(action: { showAppShareSheet() }) {
            Image(systemName: "square.and.arrow.up")
              .font(horizontalSizeClass == .compact ? .title2 : .title)
              .foregroundColor(.accentColor)
          }
          .padding()
        }
      }
    }
    

    【讨论】:

    • 这是迄今为止我遇到的最好的解决方案!巧妙使用 LPLinkMetadata
    【解决方案2】:

    我尝试了上面的代码示例来获取UIActivityViewController 中的图像。每当我们尝试将messageurlimage 共享时,图像都不会出现。如果我们只将url 添加到activityItems 中,则会出现url 中的图片。

    我检查了几个具有共享选项的应用程序,如果在共享应用程序时有文本,则不会出现图像。如果只有 url,则显示 url 中存在的图像。

    UIActivityViewController with only url

    【讨论】:

      【解决方案3】:

      图标是从您在内容中添加的链接中获取的,因此,如果您添加任何应用程序的链接,它将自动从该链接中捕获图标,您将在那里看到图标,但正如您所提到的,如果您将添加任何消息和图像在一起或任何消息和链接在一起,它只会显示您在 objectToShare 数组中附加的第一项

      【讨论】:

        猜你喜欢
        • 2021-06-05
        • 1970-01-01
        • 2020-10-06
        • 1970-01-01
        • 1970-01-01
        • 2017-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多