iOS/Objective-C:如何针对不同活动类型自定义UIActivityViewController
嘿,我来帮你理清楚这两个东西的关系,以及怎么用它们自定义UIActivityViewController的分享内容~
先搞懂UIActivityItemProvider和UIActivityItemSource的关联
其实很简单:UIActivityItemProvider是苹果官方封装好的、已经默认遵循UIActivityItemSource协议的抽象类。换句话说:
UIActivityItemSource是一套规则(协议),规定了自定义分享内容必须实现的两个核心方法UIActivityItemProvider是这个规则的“现成实现模板”,帮我们做了线程调度、异步内容加载、占位符处理等底层工作,我们只需要子类化它,重写少数方法就能快速完成自定义
两种实现方式的对比&用法
方式1:直接在VC里实现UIActivityItemSource协议(你当前尝试的)
如果你的分享内容是简单同步的(比如固定文本、本地图片),直接在视图控制器里实现协议方法就够了:
// .m文件里实现协议的两个必填方法 - (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController { // 返回和实际内容类型一致的占位符,比如分享文本就返回空字符串 return @""; } - (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(UIActivityType)activityType { // 可以针对不同分享渠道返回定制内容 if ([activityType isEqualToString:UIActivityTypeMail]) { return @"这是给邮件的专属分享文案"; } else if ([activityType isEqualToString:UIActivityTypeMessage]) { return @"这是给短信的专属分享文案"; } // 默认的通用分享内容 return @"我自定义的通用分享文本"; }
然后初始化分享控制器时,把当前VC对象作为item传入:
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[self] applicationActivities:nil]; [self presentViewController:activityVC animated:YES completion:nil];
方式2:子类化UIActivityItemProvider(更推荐复杂场景)
如果你的分享内容需要异步加载(比如从网络下载图片、请求接口获取文案),或者想把分享逻辑和VC解耦,子类化UIActivityItemProvider会更省心:
- 创建自定义Provider子类
// CustomActivityItemProvider.h #import <UIKit/UIKit.h> @interface CustomActivityItemProvider : UIActivityItemProvider @end // CustomActivityItemProvider.m #import "CustomActivityItemProvider.h" @implementation CustomActivityItemProvider // 重写这个方法返回实际分享内容,该方法在后台线程执行,放心做异步操作 - (id)item { // 模拟从网络获取分享内容 NSString *remoteText = [self fetchSharedContentFromServer]; return remoteText; } // 可选:重写这个方法做渠道适配,默认会调用上面的item方法 - (id)itemForActivityType:(UIActivityType)activityType { if ([activityType isEqualToString:UIActivityTypePostToTwitter]) { return @"推特专属分享文案"; } return [super itemForActivityType:activityType]; } // 模拟网络请求 - (NSString *)fetchSharedContentFromServer { sleep(2); // 模拟请求耗时 return @"从服务器获取的分享内容"; } @end
- 在VC里使用这个子类
CustomActivityItemProvider *itemProvider = [[CustomActivityItemProvider alloc] initWithPlaceholderItem:@"加载中..."]; UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[itemProvider] applicationActivities:nil]; [self presentViewController:activityVC animated:YES completion:nil];
总结怎么选
- 简单同步的分享需求:直接在VC里实现
UIActivityItemSource协议,代码更简洁 - 异步加载/逻辑解耦的需求:子类化
UIActivityItemProvider,苹果已经帮我们处理了线程、占位符等细节,更省心
不管用哪种方式,都可以通过activityType参数针对不同分享渠道返回定制化内容哦~
内容的提问来源于stack exchange,提问作者user6631314
相关产品推荐
相关产品推荐

