iOS 系统分享UIActivityViewController,自定义分享预览UI

UIActivityViewController继承自UIViewController,是一个系统分享组件,它提供了一些通用的标准服务(AirDrop、Messages,Mail)等,类似于照片里点击分享功能。 国内App可能用的相对较少,一般都是对接友盟分享之类的。网上针对UIActivityViewController的使用介绍虽然有不少,但是却很少有介绍分享预览时的Header区域UI定制,笔者最后在stackoverflow上找到了答案,还参考了国外大神的写法,写下了这篇文章,希望能帮助到大家。

1. 常规分享调用:

先看一下实现效果

在这里插入图片描述

代码实现

/// 调起分享器
- (void)showShareActivityVCWith:(NSArray *)messages {
    
    NSMutableArray *itemProviders = [NSMutableArray new];
    for (SDModelMessage *message in messages) {
        switch (message.type) {
            case SDMessageText: {
            	// 文本类型
                NSString *text = message.content;
                [itemProviders addObject:text];
            }
                break;
            case SDMessagePicture: {
            	// 图片类型
                NSString *filePath = @"本地路径";
                NSURL *imageUrl = [NSURL fileURLWithPath:filePath];
                [itemProviders addObject:imageUrl];
            }
                break;
            case SDMessageVideo: {
   				// 视频类型
                NSString *filePath = @"本地路径";
                NSURL *videoURL = [NSURL fileURLWithPath:filePath];
                [itemProviders addObject:videoURL];
            }
                break;
            case SDMessageAudio:
            case SDMessageFile: {
		        // 语音和文件类型
                NSString *filePath = @"本地路径";
                NSURL *fileURL = [NSURL fileURLWithPath:filePath];
                [itemProviders addObject:fileURL];
            }
                break;
            default:
                break;
        }
    }
    
    // 分享器
    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:itemProviders applicationActivities:nil];
    activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAddToReadingList];
    // 分享之后的回调
    activityVC.completionWithItemsHandler = ^(UIActivityType  _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
        if (completed) {
            // 分享成功
        } else {
            // 分享取消
            SDLog(@"cancled");
        }
    };
    [self presentViewController:activityVC animated:YES completion:nil];
}

2. 自定义分享预览:

先看一下实现效果(对外邀请):

在这里插入图片描述

首先,iOS13.0以前是不支持显示Header区域的,那么可以使用下面方法,也是网上最容易查询到的方法。

// 分享的标题
NSString *title = @"百度";
// 分享的图片
UIImage *image = [UIImage imageNamed:@"icon_logo.png"];
// 分享的url
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];

NSArray *activityItems = @[title, image, url];

UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:nil];
activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeAssignToContact];
[self presentViewController:activityVC animated:YES completion:nil];
    
// 分享之后的回调
activityVC.completionWithItemsHandler = ^(UIActivityType  _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
    if (completed) {
        // 分享 成功
    } else  {
        // 分享 取消
    }
};

注意:这里的title,image并不会对Header区域生效,activityVC会把他们和url一起拼接起来,生成分享内容。excludedActivityTypes是我们需要排除的activity; activityItems中的对象类型是可变的,可以是String、Image、URL,也可以是实现UIActivityItemSource的对象

那么iOS13.0以后究竟如何自定义Header区域,我创建了一个分享的类,专门用于处理项目中分享相关的功能,方便拓展,并优化了异常处理方案。核心代码

import UIKit
import LinkPresentation

@available(iOS 13.0, *)

@objcMembers class SDShareActivity: NSObject, UIActivityItemSource {
    
    var metadata: LPLinkMetadata?
    
    func inviteShare(_ urlString: String, sender: UIViewController) -> Void {
        let url = URL(string: urlString)!
        let provider = LPMetadataProvider()
        provider.shouldFetchSubresources = false
        provider.timeout = 0.5
        provider.startFetchingMetadata(for: url) { linkMetadata, _ in
            //linkMetadata?.iconProvider = linkMetadata?.imageProvider
            //linkMetadata?.url = url;
            //如果0.5s的超时时间内,没有获取到网页元素,走本地配置
            //这样即使是网络很差,或者断网,也都会再0.5s弹出系统分享,优化用户体验
            let metadata = linkMetadata != nil ? linkMetadata : LPLinkMetadata()
            metadata?.iconProvider = NSItemProvider(object: UIImage(named: "icon_logo")!)
            metadata?.title = NSLocalizedString("Let’s chat on Tanka!", comment: "")
            metadata?.originalURL = url
            self.metadata = metadata
            
            let activityVc = UIActivityViewController(activityItems: [self], applicationActivities: nil)
            DispatchQueue.main.async {
                sender.present(activityVc, animated: true)
            }
        }
    }
    
    // The placeholder the share sheet will use while metadata loads
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return ""
    }
        
    // The item we want the user to act on.
    // In this case, it's the URL to the Wikipedia page
    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        return NSLocalizedString("Invite Template", comment: "")
    }
        
    // The metadata we want the system to represent as a rich link
    func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
        return metadata
    }
    
}

LinkPresentation是iOS13.0新增的框架,它能够以一致的方式表示内容丰富的URL。从URL检索元数据,在应用程序中显示丰富的链接内容,并在iOS中提供共享表单体验的链接元数据。也就是说:LinkPresentation能获取URL的元数据,包括它的标题、图标和图像或视频链接。想深入了解LinkPresentation可以参考这篇文章:LinkPresentation框架详细解析

参考国外大神写法:Composing Rich Link Previews Using LinkPresentation in Swift

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UIActivityViewControlleriOS 中一个非常方便的系统原生分享组件,可以让用户快速、简单地分享内容到短信、邮件、社交平台等。 使用 UIActivityViewController 非常简单,只需要以下几步: 1. 创建分享内容 创建一个 UIActivityViewController 需要先准备好分享的内容。比如,如果要分享一张图片,则需要先将图片转换为 NSData 类型。 ``` let image = UIImage(named: "example") let imageData = UIImageJPEGRepresentation(image!, 0.5) ``` 2. 创建 UIActivityViewController 创建 UIActivityViewController 并将分享内容传入,同时也可以设置一些属性,比如分享时显示的标题、分享完成时的回调等。 ``` let activityViewController = UIActivityViewController(activityItems: [imageData!], applicationActivities: nil) activityViewController.title = "分享图片" activityViewController.completionWithItemsHandler = {(activityType, completed, returnedItems, error) in // 分享完成后的回调 } ``` 3. 显示 UIActivityViewController 最后,将 UIActivityViewController 显示出来即可。 ``` present(activityViewController, animated: true, completion: nil) ``` 这样,就可以让用户方便地分享内容了。UIActivityViewController 支持的分享平台非常多,包括但不限于短信、邮件、社交平台、打印、复制等。 需要注意的是,如果要分享的内容比较大,比如视频文件,建议使用 UIDocumentInteractionController 来实现分享功能,否则可能会出现内存问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值