我开始搜索时想知道如何与 iOS 中的其他应用程序共享。我发现有两个重要的方法是
UIActivityViewController
UIDocumentInteractionController
这些方法和其他方法在这个SO答案中进行了比较。
通常,当我学习新概念时,我喜欢看一个基本示例来帮助我入门。一旦我完成了一些基本设置,我就可以稍后按照我喜欢的方式修改它。
有很多与
UIActivityViewController
相关的问题,但我找不到任何只是要求一个简单示例的问题。由于我刚刚学会了如何做到这一点,我将在下面提供我自己的答案。请随意添加更好的版本(或 Objective-C 版本)。
使用两个按钮设置故事板并将它们连接到视图控制器(参见下面的代码)。
将图像添加到您的 Assets.xcassets 中。我称我的为“狮子”。
import UIKit
class ViewController: UIViewController {
// share text
@IBAction func shareTextButton(_ sender: UIButton) {
// text to share
let text = "This is some text that I want to share."
// set up activity view controller
let textToShare = [ text ]
let activityViewController = UIActivityViewController(activityItems: textToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
// exclude some activity types from the list (optional)
activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ]
// present the view controller
self.present(activityViewController, animated: true, completion: nil)
}
// share image
@IBAction func shareImageButton(_ sender: UIButton) {
// image to share
let image = UIImage(named: "Image")
// set up activity view controller
let imageToShare = [ image! ]
let activityViewController = UIActivityViewController(activityItems: imageToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
// exclude some activity types from the list (optional)
activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ]
// present the view controller
self.present(activityViewController, animated: true, completion: nil)
}
}
单击“共享一些文本”会在左侧显示结果,单击“共享图像”会在右侧显示结果。
excludedActivityTypes
来实现,如上面的代码所示。popoverPresentationController?.sourceView
行将导致您的应用程序在 iPad 上运行时崩溃。UIDocumentInteractionController
。分享:文字
@IBAction func shareOnlyText(_ sender: UIButton) {
let text = "This is the text....."
let textShare = [ text ]
let activityViewController = UIActivityViewController(activityItems: textShare , applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}
}
分享:图片
@IBAction func shareOnlyImage(_ sender: UIButton) {
let image = UIImage(named: "Product")
let imageShare = [ image! ]
let activityViewController = UIActivityViewController(activityItems: imageShare , applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}
分享: 文字 - 图片 - 网址
@IBAction func shareAll(_ sender: UIButton) {
let text = "This is the text...."
let image = UIImage(named: "Product")
let myWebsite = NSURL(string:"https://stackoverflow.com/users/4600136/mr-javed-multani?tab=profile")
let shareAll= [text , image! , myWebsite]
let activityViewController = UIActivityViewController(activityItems: shareAll, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}
请注意,您也可以将其用于 iPad:
activityViewController.popoverPresentationController?.sourceView = sender
因此,弹出窗口会从发件人处弹出(在这种情况下为按钮)。
如果您想共享整个屏幕,我发现这可以完美地工作。
@IBAction func shareButton(_ sender: Any) {
let bounds = UIScreen.main.bounds
UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0.0)
self.view.drawHierarchy(in: bounds, afterScreenUpdates: false)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let activityViewController = UIActivityViewController(activityItems: [img!], applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}
我已经使用了上面的实现,现在我才知道它不适用于运行 iOS 13 的 iPad。 我必须在调用present()之前添加这些行才能使其工作
//avoiding to crash on iPad
if let popoverController = activityViewController.popoverPresentationController {
popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
popoverController.sourceView = self.view
popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}
这对我来说就是这样
func shareData(_ dataToShare: [Any]){
let activityViewController = UIActivityViewController(activityItems: dataToShare, applicationActivities: nil)
//exclude some activity types from the list (optional)
//activityViewController.excludedActivityTypes = [
//UIActivity.ActivityType.postToFacebook
//]
//avoiding to crash on iPad
if let popoverController = activityViewController.popoverPresentationController {
popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
popoverController.sourceView = self.view
popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}
self.present(activityViewController, animated: true, completion: nil)
}
您可以使用我在项目的一个帮助器类中编写的以下函数。
只需致电
showShareActivity(msg:"message", image: nil, url: nil, sourceRect: nil)
它适用于 iPhone 和 iPad。如果您通过 sourceRect 传递任何视图的 CGRect 值,它也会在 iPad 中显示一个小箭头。
func topViewController()-> UIViewController{
var topViewController:UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while ((topViewController.presentedViewController) != nil) {
topViewController = topViewController.presentedViewController!;
}
return topViewController
}
func showShareActivity(msg:String?, image:UIImage?, url:String?, sourceRect:CGRect?){
var objectsToShare = [AnyObject]()
if let url = url {
objectsToShare = [url as AnyObject]
}
if let image = image {
objectsToShare = [image as AnyObject]
}
if let msg = msg {
objectsToShare = [msg as AnyObject]
}
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.modalPresentationStyle = .popover
activityVC.popoverPresentationController?.sourceView = topViewController().view
if let sourceRect = sourceRect {
activityVC.popoverPresentationController?.sourceRect = sourceRect
}
topViewController().present(activityVC, animated: true, completion: nil)
}
iOS 分享文字或图片
礼物
UIActivityViewController
let controller = UIActivityViewController(activityItems: [someObject], applicationActivities: nil)
//someObject can be UIImage, NSURL, String... iOS decide how to handle it properly
controller.popoverPresentationController?.sourceView = self.view
//add completionWithItemsHandler
controller.completionWithItemsHandler = {
(
activityType: UIActivity.ActivityType?,
completed: Bool,
arrayReturnedItems: [Any]?,
error: Error?
) in
if let error = error {
//error occured
return
}
if completed {
if let activityType = activityType {
switch activityType {
case .saveToCameraRoll:
break
case .copyToPasteboard:
break
case .addToReadingList:
break
case .airDrop:
break
default:
//all others
break
}
}
} else {
//Cancel
}
}
self.present(controller, animated: true)
将图像保存到图库中
如果要将图像保存到库中,请将
NSPhotoLibraryAddUsageDescription
添加到应用程序的 .plist
文件中,否则会出现运行时错误:
此应用程序已崩溃,因为它试图在没有使用说明的情况下访问隐私敏感数据。应用程序的 Info.plist 必须包含一个 NSPhotoLibraryAddUsageDescription 键,其中包含一个字符串值,向用户解释应用程序如何使用此数据。
此外,您可以排除此机会:
controller.excludedActivityTypes = [.saveToCameraRoll]
带有
completionWithItemsHandler
的变体,可以帮助添加后期逻辑或处理错误。
例如,将 UIImage 保存到相应处理程序中的照片库时,我遇到了下一个错误:
错误域=ALAssetsLibraryErrorDomain代码=-1“未知错误”UserInfo={NSLocalizedDescription=未知错误,NSUnderlyingError=0x600003f85110 {错误域=PHPhotosErrorDomain代码=3303“(空)”}}
正如我所想,我试图保存
CIImage
。作为变体,您可以将其转换为 CGImage
let context = CIContext()
guard let cgImage = context.createCGImage(output, from: output.extent) else { return nil }
return UIImage(cgImage: cgImage)
自定义UIActivityViewController
class ImageActivityItemSource: NSObject, UIActivityItemSource {
let image: UIImage
let title: String
public init(image: UIImage, title: String) {
self.image = image
self.title = title
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return self.image
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
return self.image
}
public func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
let image = self.image
let imageProvider = NSItemProvider(object: image)
let metadata = LPLinkMetadata()
metadata.title = self.title
metadata.imageProvider = imageProvider
return metadata
}
}
使用:
let imageActivityItemSource = ImageActivityItemSource(image: image, title: "Share this image with others")
let ac = UIActivityViewController(activityItems: [imageActivityItemSource], applicationActivities: nil)