参考书名:iOS 7 programming cookbook
出版社:O‘Reilly
作者:Vandad Nahavandipoor
问题
如何让自己开发的App出现在UIActivityViewController的分享选项中?比如,有一个文字编辑App,当你点击分享按钮的时候,ActivityViewController中能够呈现一个文本归档Archive的分享选项。当用户点击Archive按钮的时候,编辑区域的文字就能够存储到iOS设备的文件系统里。
解决方案
创建一个UIActivityViewController对象,通过这个对象分享你的内容。类UIActivityViewController的初始化方法initWithActivityItems:applicationActivities:的第二个参数决定了UIActivityViewController将呈现哪些分享选项,applicationActivities参数接受一个数组,数组对象的类型是UIActivity,因此,这里我们定义一个UIActivity子类,并且实现UIActivity类中一些必要的方法,然后,传递给UIActivityViewController的初始化方法initWithActivityItems:applicationActivities:
探讨
这里,我们创建一个activity,实现反转字符串的功能。记住,类UIActivityViewController的初始化方法initWithActivityItems:applicationActivities的参数nitWithActivityItems接受一个任意类型的数组,可能包括字符串,数字,图像等,因此,我们的activity需要遍历activityItems数组,检查是否存在字符串对象,并且提取所有字符串对象,然后反转所有的字符串对象,并且在一个alertview窗口中显示。
1.定义UIActivity的子类StringReverserActivity .在iOS 8中,使用UIAlertController创建提示窗口,废弃了之前的UIAlertView类,并且使用View Controller 的PresentViewController:animated:completion:方法显示UIAlertController。因此,StringReverseActivity定义一个StringReverseActivityDelegatele类型的代理,代理对象实现了方法stringReverseDidFinishWithMessage:用于显示UIAlertController窗口。
#import <UIKit/UIKit.h>
@protocol StringReverseActivityDelegate<NSObject>
- (void)stringReverseDidFinishWithMessage:(NSString *)message;
@end
@interface StringReverseActivity : UIActivity
@property(weak, nonatomic) id<StringReverseActivityDelegate> delegate;
@end
2.重写activityType方法,该方法返回的字符串表示activity的标志符,通常由bundleid和activity类型字符串组成。
- (NSString *)activityType{
NSString *bundleIdentifier=[[NSBundle mainBundle] bundleIdentifier];
return [bundleIdentifier stringByAppendingString:NSStringFromClass([StringReverseActivity class])];
}
3.重写方法activityTitle,返回的字符串将会在activity view controller里出现,表示activity的标题
- (NSString *)activityTitle{
return @"Reverse String";
}
4.重写方法activityImage,该方法返回的对象类型是UIImage。如果您的app在iPhone中运行,请确保为Retina屏幕和非Retina屏幕提供不同尺寸的图片,Retina屏幕的图像像素为86x86,显然非Retina屏幕的图像尺寸为43x43.iOS仅仅使用图像的alpha通道(alpha channel),因此,确保图片的背景是透明的(可以使用ps 的魔术棒选取背景,然后delete,然后,在通道图层中,分离通道,即可得到一张只有alpha通道的图片)
- (UIImage *)activityImage{
return [UIImage imageNamed:@"reverse"];
}
6.实现方法canPerformWithActivityItems:,返回bool类型指示是否能够执行动作。当activity View Controller调用初始化方法initWithActivityItems:applicationActivities:时候,会把第一个参数传递给canPerformWithActivityItems。记住,activityItems数组包含的对象的类型是任意的,我们需要遍历这个数组,检查是否含有activity能够处理的对象类型。
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems{
for (NSObject *obj in activityItems) {
if ([obj isKindOfClass:[NSString class]]) {
return YES;
}
}
return NO;
}
7.实现方法prepareWithActivityItems:,如果方法canPerformWithActivityItems返回yes,这个方法将会被activity调用,在这个方法里面,遍历activityItems数组,提取符合要求的对象,并且存储,用于后来的操作。
- (void)prepareWithActivityItems:(NSArray *)activityItems{
NSMutableArray *mutableArray=[NSMutableArray array];
for (NSObject *obj in activityItems) {
if ([obj isKindOfClass:[NSString class]]) {
[mutableArray addObject:obj];
}
}
self.activityItems=[NSArray arrayWithArray:mutableArray];
}
8.实现方法performActivity,这个方法包含了activity真正要执行的操作。在本例子中,该方法遍历方法prepareWithActivityItems:中获得的数组,并且反转数组中的字符串,然后调用代理对象的方法stringReverseDidFinishWithMessage:呈现UIAlertController。
//反转字符串
- (NSString *)reverseString:(NSString *)str{
NSMutableString *mutableString=[NSMutableString stringWithCapacity:str.length];
for (NSInteger i=str.length-1; i>=0; i--) {
[mutableString appendFormat:@"%c",[str characterAtIndex:i]];
}
return [NSString stringWithString:mutableString];
}
- (void)performActivity{
NSMutableString *mutableString=[NSMutableString string];
for (NSString *str in self.activityItems) {
[mutableString appendString:[NSString stringWithFormat:@"%@\n",[self reverseString:str]]];
}
NSString *result=[NSString stringWithString:mutableString];
[self.delegate stringReverseDidFinishWithMessage:result];
}
以上为自定义UIActivity的实现过程,接下来,view Controller中添加一个按钮,绑定点击事件处理方法。在点击处理方法中,实例类型StringReverseActivity,设置view controller为它的代理,实现代理方法。初始化activity view controller,传递string reverse activity对象作为activity view controller的一个分享选项。
- (IBAction)shareContent:(id)sender {
StringReverseActivity *stringReverseActivity=[[StringReverseActivity alloc] init];
stringReverseActivity.delegate=self;
self.activityViewContoller=[[UIActivityViewController alloc] initWithActivityItems:@[@"item1",@"item2",@"item3"] applicationActivities:@[stringReverseActivity]];
[self presentViewController:self.activityViewContoller animated:YES completion:nil];
}
- (void)stringReverseDidFinishWithMessage:(NSString *)message{
UIAlertController *alertController=[UIAlertController alertControllerWithTitle:@"反转字符串" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction=[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *okAction=[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
}
图2.分享视图
图3 反转结果