iOS Widget开发

来源:互联网 发布:java ftp断点续传 编辑:程序博客网 时间:2024/05/22 03:42

前言:

想了解什么是Widget的童鞋请绕道,想在项目中添加Widget的同学,请耐心往下看

首先看一下我们需要实现的效果:仿网易云音乐和仿支付宝两个效果

  

总效果图(左)  仿网易云音乐展开后的效果图(右)


一、打开你的Project,添加一个Today Extension

首先,打开Target,然后点左下角的“+”,在“iOS”选项下边找到Application Extension,然后选择“Today Extension”,如图1、图2所示:


图1 添加Target




图2 找到Today Extension


然后点击Next,填写Target名称,这里是“HJFirstWidget”,下一步会有一个激活的弹窗,点击激活按钮,如图3所示


图3 激活Target


激活之后,就添加好了,如图4所示,这时候你需要改Deployment Target,也就是最低支持的系统版本,需要注意的是Widget是iOS 8的新特性,因此此处的Deployment Target不能低于iOS 8.0;


图4 添加Today Extension完成以及需改Deployment Target示意图


这时候,运行项目就可以在通知页面看到一个空的Widget效果了,此时默认的视图控制器是TodayViewController,与之对应的是一个叫“MainInterface”的storyboard,如果需要纯代码布局,那么就要在plist文件最下边的NSExtension里修改一些配置,删除NSExtensionMainStoryboard键值对,新增NSExtensionPrincipalClass键值对,修改之前如图5所示,修改后如图6所示


图5 未修改配置的示意图



图6 修改配置后的示意图

需要说明的是:我们添加的Target叫Extension,最初创建的项目叫Containing APP

运行Containing APP,效果图如图7所示


图7 更改完配置后运行效果图


到这一步呢,项目基本成型,只需要我们在TodayViewController里边添加相应的空间即可实现相应的效果,下边我们将实现Widget最难也是最重要的功能

二、共享数据

要想通过Widget和Containing APP共享数据需要对他们分别进行配置,首先我们对Containing APP配置

打开Target,点击capability选项,找到APP Groups,点击右侧打开按钮,并添加Item,如图8 所示,配置完成之后再项目中会看淡一个后缀为.entitlements的文件;


图8 打开APP Groups以及添加Item示意图

然后配置Widget,操作同上步,操作完成后效果图如图9所示


图9 配置Widget完成后效果图

此时配置已经完成,通过相应代码即可实现数据共享,我们都知道,Extension 和 Containing APP之间共享数据的方式有两种,NSUserDefaults和NSFileManager,

1.通过NSFileManager存取:

存数据:

/** 通过NSFileManager存数据 @return 是否存储成功 */- (BOOL)saveDataByNSFileManager{    NSError *err = nil;        /**    这里的groupIdentifier是在APP Groups里添加的Item    **/    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.hjfirst"];    containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/widget"];        NSString *value = @"你要存的内容";    BOOL result = [value writeToURL:containerURL atomically:YES encoding:NSUTF8StringEncoding error:&err];    if (!result)    {        NSLog(@"存入数据失败,原因 : %@",err);    }    else    {        NSLog(@"存入数据成功,数据 : %@ success.",value);    }    return result;}

取数据:

/** 通过NSFileManager读取数据 @return 读取到的数据 */- (NSString *)readDataByNSFileManager{    NSError *err = nil;    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.hjfirst"];    containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/widget"];    NSString *value = [NSString stringWithContentsOfURL:containerURL encoding:NSUTF8StringEncoding error:&err];    return value;}


2.通过NSUSerDefaults来共享数据

存数据:

/**    这里是采用NSUserDefaults来实现   **/    NSUserDefaults *sharedDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.hjfirst"];    [sharedDefault setObject:@{@"name" : [_titleArray objectAtIndex:sender.tag - 120]} forKey:@"firstStatus"];    [sharedDefault setBool:NO forKey:@"isSendData"];    [sharedDefault synchronize];

取数据

/**    这是一个获取Today Extension数据的例子    **/    NSUserDefaults *sharedDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.hjfirst"];    NSLog(@"共享的数据 : %@",[sharedDefault objectForKey:@"firstStatus"]);


三、通过Extension唤醒Containing APP

如果想通过Extension唤醒Containing APP,需要在Containing APP的Target进行配置,在Info的URL Types里边新增一项内容,配置后效果图如图10所示


图10 配置Containing APP效果图


配置完上述信息之后,就可以通过代码唤醒Containing APP,示例代码如下,其中://后边的内容是传递的参数,用以区分响应不同的事件

/*     这里的URL是有固定格式的,://前边的“hjWidgetDemo”是Containing APP添加的URL Types里添加的URL Schemes,这里是必须一致,否则会跳转失败的     */    NSString *urlString = [NSString stringWithFormat:@"hjWidgetDemo://action=%ld",sender.tag-120];        [self.extensionContext openURL:[NSURL URLWithString:urlString] completionHandler:^(BOOL success) {        if (success == YES) {            NSLog(@"跳转成功");        }        else        {            NSLog(@"跳转失败");        }    }];

四、iOS 10新特性

Widget可以折叠和展开,示例代码:

/*     设置Widget的样式,这是iOS 10的新特性,也就是所谓的“折叠”、“打开”模式,     NCWidgetDisplayModeCompact, // Fixed height     NCWidgetDisplayModeExpanded, // Variable height     */    self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;

系统封装的有点击折叠或者展开按钮的方法:

/** 这是Widget改变展示样式时候的回调  @param activeDisplayMode activeDisplayMode @param maxSize 尺寸 */- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize{    }



最终效果图为:



注意事项:

  1. Widget的展开和折叠是iOS 10的新特性,在iOS 8 到iOS 10 之间的系统只支持类似于折叠起来的效果;
  2. 如果需要自定义Widget某一部分控件的背景颜色,需要设计透明度,因为TodayViewController的背景色有透明度的,在不同颜色桌面壁纸上显示效果有较大差异;
  3. Widget目前暂不支持输入内容,只能做展示以及点击事件,也就是说不能再TodayViewController里边添加输入类的控件,比如说UITextField、UITextView等; 

特别说明:如果发现错误或者不合理的地方,恳请批评指正


源码下载地址:https://github.com/HJZone/HJWidgetDemo


原创粉丝点击