新的IOS6增加了一些新特性。因为应用需要,所以在国庆的几天里。研究了一下IOS6的说明文档,然后大概地总结了一下UIActivityViewController的用法与大家分享。

首先 从实际效果入手,上两张图。

在iphone和ipod touch上采用模态呈现

IOS6 新特性之UIActivityViewController详解-LMLPHP

而在ipad上 则采用Popoverview方式弹出

IOS6 新特性之UIActivityViewController详解-LMLPHP

虽然在iphone 和 ipad上的展现方式不同 但是 它们展现的都是一个东西。

这也就是此次要谈及的新特性的关键   UIActivityViewController

The UIActivityViewController class is a standard view controller that you can use to offer various services from your application.(引用文档原话)

即该viewcontroller是一个用来提供各种各样的服务的一个标准的viewcontroller。

如图 可以提供E-mail Twitter Facerbook 等分享。(由于是模拟器打印等操作没有呈现出来 而最后的RenRen是我自己添加的 稍后会提到之一)

说一说我自己的理解。

其实UIActivityViewCOntroller 管理着的那个View 以固定的形式展现出来(模态 或者 PopoverView)。

View中的内容 是使用各类服务的按钮。IOS6自带的标准服务有E - mail,各类大型社交网络的分享,打印,拷贝,保存等等。(成为ActivityType 稍后也会提到之二)

当然 自己也可以添加一些服务,比如上图所示的人人一键分享。那个爱心 以及 文字都是自定义的 当然 点击后 也会有个自定义方法。

说了这么多文字性质的,那么接下来 就从代码角度看一看这个UIActivityViewController到底是如何工作的了。

Test *dz = [[Testalloc]init];

//这UIActivityRenren 对应的便是RenRen的那个按钮 稍后提到之一

NSArray *activity = [[NSArrayalloc] initWithObjects:dz,nil];

NSArray *activityItems = [[NSArrayalloc]initWithObjects:

//保存 分享等服务的方法 需要传入文字和图片 这个NSArray中保存的就是这个。

@"Padgram",

@"Dz",

[UIImageimageNamed:@"background1.png"],nil];

// 初始化一个UIActivityViewController 2个参数 第一个是服务所需参数 第二个是自定义添加的服务列表

UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems            applicationActivities:activity];

// 写一个bolck,用于completionHandler的初始化

UIActivityViewControllerCompletionHandler myBlock = ^(NSString *activityType,BOOL completed)
{

NSLog(@"%@", activityType);

if (completed) {

NSLog(@"completed");

} else

{

NSLog(@"cancled");

}

[activityVC dismissViewControllerAnimated:YEScompletion:Nil];

};

// 初始化completionHandler,当post结束之后(无论是done还是cancell)该block都会被调用

activityVC.completionHandler = myBlock;

// 以PopoverView方式展现出UIActivityViewController

self.sharePopover = [[UIPopoverControlleralloc] initWithContentViewController:activityVC];

[self.sharePopover    presentPopoverFromRect:self.shareBtn.frame

inView:self.view

permittedArrowDirections:UIPopoverArrowDirectionAny

animated:YES];

由上述代码可以总结出UIActivityView的三要素 初始化 completionHandler 以及呈现方式

一、初始化方法

initWithActivityItems:activityItems applicationActivityies:activity

有两个参数。第一个 activityItems 是调用服务时传递给服务的一个数据数组 里面可能有你要email 分享 或者 打印等的 文字 或图片。

第二个 activity 是一个数组 里面存放着UIActivityRenren  这个参数便是我们自定义添加的服务数组

二、completionHandler

这是UIActivityViewController的两个参数之一

ps: 另外一个参数是excludedActivityTypes 类型为NSarray 可以理解为禁用服务列表

例如 该属性中存在元素UIActivityTypeMail 则UIActivityView中则没有Mail这个服务选项。

当用户完成了服务的选择操作,或者当用户释放了view controller

         那么viewcontroller会执行completion handler,以便让你的应用程序知道用户操作的最终结果。

此处笔者由于水平十分有限。。也没有弄得特别明白 十分抱歉。

三、呈现方式

之前已经提过

iphone或者ipod touch 使用模态方式呈现 例:[self presentViewController:activityVC animated:YEScompletion:Nil];

ipad则用PopoverVIew呈现 如代码中所写

那么 接下来就该把前文中一些没有提及的给补充起来 其中 最为重要的是UIActivity

UIActivity 是一个抽象类,用于提供一些特定程序的服务。

它和UIActivityViewController对象联合起来使用,为用户呈现一些相关服务。

众所周知,抽象类无法直接生成对象。只能以它为父类,生成一些子类。

在IOS6中,已经有一些写好的UIActivity子类。比如 e-mail,Facebook,sinaweibo等服务。

但是仅仅是这些自带的,是远远不能满足用户的需求的。比如 对中国用户 而已 他们需要一键分享到人人的服务,这个类似sinaweibo。可是 IOS6原生并不自带这个服务。所以需要自己去写,也就是 subclass UIAcitivity 然后 复写父类的一些方法。

以下摘自IOS6说明文档

Methods to Override

When subclassing, you must always override the following methods and use them to provide information about your service:

  • - (NSString *)activityType
  • - (NSString *)activityTitle
  • - (UIImage *)activityImage
  • - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems;
  • - (void)prepareWithActivityItems:(NSArray *)activityItems;

UIActivityViewController object,
which is responsible for presenting services to the user.

翻译过来就是 要继承UIActivity 至少要复写以上5个方法 然后 和 UIActivityViewController对象一起实现自定义服务。

这五个方法中的前三个 顾名思义 第一个是activityType 说到这个 便把上文的稍后提到之二一并写出

IOS6是自带了一些标准服务的  如e-mail 打印 分享至各类社交网络 那么 这些便是不同的activityType

下面贴上一个标准服务的ActivityType表

Constants

Built-in Activity Types

Activity types for which the system has built-in support.

NSString *const UIActivityTypePostToFacebook;

NSString *constUIActivityTypePostToTwitter;

NSString *constUIActivityTypePostToWeibo;

NSString *constUIActivityTypeMessage;

NSString *constUIActivityTypeMail;

NSString *constUIActivityTypePrint;

NSString *constUIActivityTypeCopyToPasteboard;

NSString *constUIActivityTypeAssignToContact;

NSString *constUIActivityTypeSaveToCameraRoll;

回到原题 activityType这个方法就是要你 返回一个NSString 作为该UIActivity的Type

第二个和第三个 则是在UIActivityView中显示的标题和图标 返回值分别是NSString 和 UIImage

第四个返回YES or NO表示该服务是否在UIActivityView中显示

而第五个最为重要 这个方法里面写的是 点击服务后(该方法会受到ActivityItems参数)  要做的事 你们可以先NSLog体会一下(这里面写的就是各种服务了 比如一键人人)

实战遇到的问题

Question1 :如果在设置中没有事先登陆各类分享账号 那么弹出的UIActivityView中便没有对应的服务。。。坑爹啊= =不是应该点了之后提示设置的么

时间关系。。这个我稍后再解决。。。。

另外 我看到一些人反应说有些标准服务 比如 微博 facebook 显示不了 这个问题可能的原因之一 是你设定activityItem时 添加了不该添加的东西= = 让我们先来看一看帮助文档

UIActivityTypePostToFacebook

The object posts the provided content to the user’s wall on Facebook. When using this service, you can provideNSStringNSAttributedStringUIImageAVAsset,
and NSURL objects
as data for the activity items. You may also specifyNSURL objects
whose contents use the assets-library scheme.

以Facebook服务为例 它只能以NSString,NSAttributedStringUIImageAVAsset,
and NSURL这些类作为其activityItem的数据
如果有其他的对象包含在里面 那么 在UIActivityView上 是不会显示Facebook的服务的。

通过后来的实验发现另外一个导致这种情况的原因,而且应该是出现该问题最主要的原因,就是用户并没有在设置里面添加对应的账户。比如没有添加facebook的账户 uiactivityview里面 便没有facebook的选项。

其次 要注意到的是,模拟器中 虽然我们没有设置对应的社交网络的账号。但是,它的uiactivityview 中所有的服务 facebook twitter 以及新浪微博 都是存在的。这是因为 某个检测设备是否关联了对应服务的方法,在模拟器上 无论实际情况如何 它返回的值都是true 也就意味着 关联的对应服务。所以才能得以在uiactivityview上显示所有的服务。这个方法如下(检测新浪微博是否关联)

[SLComposeviewcontroller isAvailableForServiceType:SLServiceTypeSinaWeibo];

有兴趣的可以自行在IOS6的特性文档中查询一下SLComposeviewcontroller

在之后的介绍文章中 我也会针对SLComposeviewcontroller做一些介绍。

05-11 13:03