使用UIActivityViewController分享图片,没有preview

以前都是用第三方sdk来分享的,最近使用官方的UIActivityViewController来做分享,结果分享图片的时候preview不了分享的图片。

自定义一个继承UIActivityItemProvider的类。关于分享的内容自定义可以自己实现UIActivityItemSource这个协议。首先看看协议的订阅,当我看到有一个返回thumbimage的接口时候,第一感觉就是它是我需要的。

复制代码
@protocol UIActivityItemSource <NSObject>

@required

- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController;	// called to determine data type. only the class of the return type is consulted. it should match what -itemForActivityType: returns later
- (nullable id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(nullable UIActivityType)activityType;	// called to fetch data after an activity is selected. you can return nil.

@optional

- (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(nullable UIActivityType)activityType; // if activity supports a Subject field. iOS 7.0
- (NSString *)activityViewController:(UIActivityViewController *)activityViewController dataTypeIdentifierForActivityType:(nullable UIActivityType)activityType; // UTI for item if it is an NSData. iOS 7.0. will be called with nil activity and then selected activity
- (nullable UIImage *)activityViewController:(UIActivityViewController *)activityViewController thumbnailImageForActivityType:(nullable UIActivityType)activityType suggestedSize:(CGSize)size; // if activity supports preview image. iOS 7.0
- (nullable LPLinkMetadata *)activityViewControllerLinkMetadata:(UIActivityViewController *)activityViewController API_AVAILABLE(ios(13.0)); // called to fetch LinkPresentation metadata for the activity item. iOS 13.0

@end

结果测试发现,这个方法再iOS17上根本不触发,应该是iOS13以前就用上面几个,iOS13后就用LPLinkMetadata的方法。LPLinkMetadata中有一个imageProvider,他就是preview的内容。

复制代码
 public func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
    let metadata = LPLinkMetadata()
    metadata.title = "My title" // Preview Title
    metadata.originalURL = URL(string: "You sub title here") 
    // Set image 
    metadata.imageProvider = NSItemProvider(object: image)
    
    return metadata
}

感觉完成了,但是测试的时候有发现问题了,preview没有铺满那个区域。搜索了一下,发现是图片有alpha透明的区域。对应的处理方法就是去掉透明区域。

复制代码
extension UIImage {
    func adjustedForShareSheetPreviewIconProvider() -> UIImage {
        let replaceTransparencyWithColor = UIColor.black // change as required
        let minimumSize: CGFloat = 40.0  // points

        let format = UIGraphicsImageRendererFormat.init()
        format.opaque = true
        format.scale = self.scale

        let imageWidth = self.size.width
        let imageHeight = self.size.height
        let imageSmallestDimension = max(imageWidth, imageHeight)
        let deviceScale = UIScreen.main.scale
        let resizeFactor = minimumSize * deviceScale  / (imageSmallestDimension * self.scale)

        let size = resizeFactor > 1.0
            ? CGSize(width: imageWidth * resizeFactor, height: imageHeight * resizeFactor)
            : self.size

        return UIGraphicsImageRenderer(size: size, format: format).image { context in
            let size = context.format.bounds.size
            replaceTransparencyWithColor.setFill()
            context.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
            self.draw(in: CGRect(origin: .zero, size: size))
        }
    }
}

如果不想处理图片大小的就直接去掉alpha通道

复制代码
func removingAlpha() -> UIImage {
        let format = UIGraphicsImageRendererFormat()
        format.opaque = true // removes Alpha Channel
        format.scale = scale // keeps original image scale
        return UIGraphicsImageRenderer(size: size, format: format).image { _ in
            let size = context.format.bounds.size
        	UIColor.whiteColor.setFill()
        	context.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
            draw(in: CGRect(origin: .zero, size: size))
        }
    }

这下就正常了。

Referene:

https://stackoverflow.com/questions/57850483/ios13-share-sheet-how-to-set-preview-thumbnail-when-sharing-uiimage

https://nemecek.be/blog/189/wip-sharing-data-with-uiactivityviewcontroller-tips-tricks

相关推荐
sweet丶37 分钟前
iOS内存映射技术:mmap如何用有限内存操控无限数据
ios·操作系统·app
漫天星梦6 小时前
iOS 手机无法播放视频问题排查与解决方案记录
前端·ios
如此风景10 小时前
IOS UIKit 相关知识
ios
QuantumLeap丶12 小时前
《Flutter全栈开发实战指南:从零到高级》- 22 -插件开发与原生交互
android·flutter·ios
2501_9159214313 小时前
混合开发应用安全方案,在多技术栈融合下构建可持续、可回滚的保护体系
android·安全·ios·小程序·uni-app·iphone·webview
Sheffi6613 小时前
RunLoop Mode 深度剖析:为什么滚动时 Timer 会“失效“?
ios·objective-c
QuantumLeap丶13 小时前
《Flutter全栈开发实战指南:从零到高级》- 21 -响应式设计与适配
android·javascript·flutter·ios·前端框架
2501_9151063214 小时前
Charles抓包怎么用 Charles抓包工具详细教程、网络调试方法、HTTPS配置与手机抓包实战
网络·ios·智能手机·小程序·https·uni-app·webview
00后程序员张14 小时前
Fastlane 结合 开心上架,构建跨平台可发布的 iOS 自动化流水线实践
android·运维·ios·小程序·uni-app·自动化·iphone
wjm04100614 小时前
秋招ios面试 -- 真题篇(三)
ios·面试·职场和发展