iOS 10 Widget

作者: 不多满 | 来源:发表于2016-07-14 22:35 被阅读12605次

    环境:xcode8.0 beta,iOS 10 beta2

    目录
    1、前言
    2、新特性
    3、适配问题

    一、前言

    前面一篇iOS开发之widget实现文章说到了如何在iOS 8.0-9.3上实现widget,可是iOS 10已经来袭,不了解一下iOS 10,把widget适配上去,说不过去呀!所以,本篇文章就接着说下iOS 10上面Today Widget的坑坑洼洼。

    二、Today Widget新特性

    安装完iOS 10的beta版本,发现苹果越发重视widget了:快速浏览,及时从喜爱的应用中了解信息,如图1所示。
        现在,从锁屏页面,下拉通知栏的第一页,还有左滑主页面都可以进入widget。通过右上角的“展开”、“折叠”按钮,可以查看widget的全部内容和部分内容。在6s上面,点击应用icon的3D Touch界面中,也会有widget的折叠界面。


    iOS10 Today Widget界面.png

    三、适配问题

    1、在widget中,展开、折叠具体是怎么实现的呢?

    在NSExtensionContext中,新添了widgetLargestAvailableDisplayMode属性,来确认当前widget是展开还是折叠状态。所以,先在viewWillAppear中设置widget的mode为展开。
    代码段1
    - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded; }
        然后,就是展开和折叠的处理了。在NCWidgetProviding协议中,新添了这么个方法widgetActiveDisplayModeDidChange,不赘述,直接用代码示例说明它的用途:
    代码段2
    // If implemented, called when the active display mode changes. // The widget may wish to change its preferredContentSize to better accommodate the new display mode.
    - (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize { if (activeDisplayMode == NCWidgetDisplayModeCompact) { self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110); } else { self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300); } }
        到这里,你可以在iOS 10上面看到带有展开、折叠功能的widget了,具体UI上面的微调,这里暂且不表,聪明的你肯定早就知道解决方案了。但是,不要着急,容我再把自己遇到的坑给家接着叨叨。

    2、启动app后,第一次显示的是折叠,而不是展开呢?

    这个问题,归咎于preferredContentSize的设置,确认widget的mode之前,不要设置这个值。我的处理方式是:在widgetActiveDisplayModeDidChange中设置展开或折叠状态下widget的高度,就如上面的代码段2一样(当然,我的项目里比这个处理要复杂的多,这里化繁为简只为示例),iOS 10环境下在这里设置高度也就足够了。

    3、为什么有时展开或折叠"失灵"了,没有对应的展开或折叠呢?

    这个问题的前提,肯定是你展开、折叠对应的widget高度不一样,只是看到了右上角按钮内容改变,但高度却没有变。
        这个问题的原因在于,点击展开、折叠按钮修改了widget的mode之后,却没有设置对应的高度:preferredContentSize。怎么办呢?再回到代码段2,mode改变后,设置对应状态下的高度即可。

    4、如何用XCode 7.3打出能够适配iOS 10的widget呢?

    适配完iOS 10,会发现代码中总不能用XCode 8.0 beta打包代码吧,可是用XCode 7.3打包代码也编译不过啊,widgetLargestAvailableDisplayMode和NCWidgetDisplayMode都是iOS 10的产物。
        用kvc试试看?对,就是kvc。闲言不表,直接看代码吧:
    代码段3 相对于 代码段1
    - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.extensionContext setValue:@"1" forKey:@"widgetLargestAvailableDisplayMode"]; }

    代码段4相对于 代码段2
    - (void)widgetActiveDisplayModeDidChange:(NSInteger)activeDisplayMode withMaximumSize:(CGSize)maxSize { if (activeDisplayMode == 0) { self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110); } else { self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300); } }

    5、切记:UI的更新要在主线程操作哈!!!比如酱紫:

    //通知主线程刷新 dispatch_async(dispatch_get_main_queue(), ^{ //...........; });
    好了,我在适配widget过程的问题就这些了,希望可以帮助正在开发widget遇到同样问题的朋友。

    End

    相关文章

      网友评论

      • 柏林日记:请问,如何判断App的widget是否被用户添加了呢
      • 就是很随意哦:请问楼主,怎么判断是否锁屏呢,我的需求是锁屏和截屏状态的UI不一样
      • __LuckyPan__:你好,我想请教一个问题,我的widget高度是固定的,但是不管怎么设置控制台都会打印出“No active animation block!”,网上也没有找到很好的解决方案,不知道什么原因,还请赐教。
      • 被帅醒的小吴同志:感谢楼主分享~
      • 328b7047934f:您好,请问可不可以不通过点击“展开”按钮来实现widget的展开,而是通过点击里面的按钮来实现?
        MichaelHuyp:问下楼主 怎么样做到不打开app 在Wedget Extension界面进行网络请求拉取数据更新界面呢?
        328b7047934f:@三月米果 谢谢!
        不多满:@勇氣君 还真没试过,明天我试试。我猜想是不可以的,这个是系统提供的方法,第一次展开时,肯定还是要通过系统的按钮来实现。
      • 风听海水听石:看了一下上面的问题,我也是想隐藏展开折叠按钮,但我的问题有点特殊,我没有设置widgetLargestAvailableDisplayMode,按钮还是没有隐藏。还有小编说的隐藏展开折叠按钮系统就会默认110高度,但是我仔细看了一些APP,网易云音乐,今日头条...,等都是没有展开折叠按钮的,但他们的高度很高,绝对超过了110
        风听海水听石:@三月米果 我把APP都跟新了一下,36氪 APP你有没有,上面没有展开折叠按钮,高度4百多,可惜这里没法发送图片,不然就截图给你看看了

        不多满:@fruits 我刚才看了下头条的widget,是有展开折叠的,你的是不是老版本的,老版本的是没有展开折叠的
        风听海水听石:@fruits 按钮隐藏了
      • 热风in:已关注 希望能加一下qq交流 🙏
      • 热风in:作者 求助 我通过 NSUserDefaults*shared = [[NSUserDefaults alloc]initWithSuiteName:@"group.com.yuanin.widge"]; 存储的数据在widget上没拿到 请教一下可能是什么原因
        热风in:@三月米果 除了 数据的问题 还有一个是你上面提到的 sdtouch 唤起的问题
        热风in:@三月米果 设置正确了 我之前测试的时候 数据是正常的 但是发版了之后有问题 我是用xcode7.3 打的包
        不多满:@热风in Capibilities里面的app group设置正确了么?然后再确认主app里面数据写进去没有?
      • 扑倒的柔情:请问楼主,我用Xcode7.0.1打包出来widget的背景颜色和以前一样是黑色半透明,如何将widget的背景颜色如何改成那种白色的毛玻璃效果?
      • DefaultYuan:最近用swift写了一个iOS10上的widget,10上面有折叠功能(https://github.com/DefaultYuan/iOS10WidgetDemo
        DefaultYuan:@风吹柳絮如花落 缺少啥文件
        风吹柳絮如花落:@DefaultYuan 跑不起来,缺少文件
      • 站在能者之肩:您好,我想在3Dtouch 这里。把3Dtouch的菜单放到 widget 的下面展示,即 widget 在上 功能菜单在下面显示。怎么解决呢,谢谢啦
        stoicer:这个问题是个坑,其实根本不是什么问题。APP单独放到手机桌面就可以了,不要放到组里面,坑啊
        stoicer:我也在做这个样式,我看很多APP,包括支付宝都是上面放widget,下面是3D Touch的功能菜单,请问这么解决呢
      • 红尘安乐_si:您好 ,我看了你的这篇文章 ,用你的方法尝试了一下 ,然而在折叠情况下 self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110);这里的110是系统默认的高度,修改数值并不能调整高度,希望你能帮忙解除我的疑惑:怎么才能实现高度的调整。
      • 小包包包:而且ios8.0.2上载入不出来,显示无法载入
      • 小包包包:楼主,我用xcode8 调适 8.0.2,崩溃在
        [self.extensionContext setValue:@"1" forKey:@"widgetLargestAvailableDisplayMode"];

        说没有这个key,怎么解决?如果不用这个的话,用xcode7又编译不过
        站在能者之肩:@小包包包 你升级xcode8 就行了啊
      • Python数据分析实战:请问在提交版本的时候,需要为Widget单独在添加证书吗
        不多满:@SilenceYaung 是的,widget独立于主app,需要证书。
      • superherohui:很好用
      • af006b386e42:请问楼主,我不使用折叠展开模式,让widget的默认高度为180,怎么实现,我这发现设置preferredContentSize没用,总是110
        af006b386e42:@三月米果 OK,明白!谢谢
        不多满:@徐永波 不使用展开折叠,还要设置高度180的话,那就用xcode7.3打包了吧。
      • 退休老干部:收藏一下,以后可能有用
      • Kara万:厉害啊。但是请教下如何能让widget不显示在3dtouch的界面呢?
        7d4bb5d59ee5:@Magic_YY 用Xcode7.3编译打包啊~
        寂灭天骄小童鞋:@Kara万 请问一下,不让widget显示在3d touch上,你完成了么?
        不多满:@Kara万 系统自带功能,我办不到了 :joy:
      • 俞海波:想问下如果不用折叠,高度怎么适配呢,以前的方法:self.preferredContentSize = CGSizeMake(self.view.bounds.size.width, 220);并不管用了
        xipi000:iOS10 默认不设置折叠功能的话,默认高度110 是不能修改了!
        修改背景色 self.view.background
        俞海波:我的意思是如果不设置折叠功能,viewdidload里设置高度self.preferredContentSize = CGSizeMake(self.view.bounds.size.width, 220);不管用了,高度一直是默认高度。还有个问题,它默认是一个白色透明的背景,怎么换成其他透明色呢。
        不多满:@俞海波 不明白你的具体需求是什么,如果在展开的状态去设置高度,需要在widgetActiveDisplayModeDidChange里面去设置,一般是没有问题的,你可以试试看。
      • walle刘:请问一下楼主 我现在想要设置的是 widget 没有展开收缩的操作, 但是高度设置不了 总是默认的是怎么回事?
        不多满:@walle刘 iOS10默认高度就是固定的110,没有设置展开的话,就不能调整他的高度。
      • FingerStyle:请问一下楼主,如何设置UIApplicationShortcutWidget的值,我们app上面有个today extension,我设置了这个extension的bundleID, 但是发现使用3DTouch的时候,today extension是收缩的,而且无法展开。
        不多满:@FingerStyle 3DTouch的时候只有折叠状态的,如果没有添加widget至today页面,会有个添加至widget按钮。
      • martin丶灬:如何隐藏右上角的展开和折叠的那个按钮呢
        voliet轩:题主解决了吗
        martin丶灬:@三月米果 我知道不设置widgetLargestAvailableDisplayMode能隐藏 不过这样的话 每次展开的 不是适配好的高度 而是系统默认的110 我用xcode8
        不多满:@martin丶灬 不设置widgetLargestAvailableDisplayMode就好了,不过这样的话,你就只能看到折叠状态的。如果要展开,就会展示那个按钮。(前提:你用的xcode8)
      • 阿转转:刚刚试了用Xcode7.3打的包,在iOS10上也没有展开和折叠的按钮啊?是怎么回事?
        不多满:@阿转转 重点不在kvc,kvc只是为了编译通过,重点在于你的Xcode不支持ios10的库
        阿转转:@三月米果 用kvc设置了,依旧无效
        不多满:@阿转转 你得用xcode8 beta打包,Xcode7.3不支持iOS10,所以我的代码中用kvc设置展开折叠的mode
      • 阿转转:用到了,谢谢分享
      • 金康帅:写的很有用。
      • 梨不知:请问ios10里如何将widget添加到主页呢,就是通过3d touch把widget添加到快捷菜单里
        不多满:@卡卡西西_369 你的展开、折叠功能正常么?是不是因为你的折叠状态下,显示的widget不对导致的。
        55a965af3a7d:@三月米果 我用xcode 8编译了项目在6s上3D Touch下并没有出现的添加widget的选项,该怎么处理了,希望帮忙看一下
        不多满:@Vircky 只管添加widget代码就好,3D Touch下的快捷菜单就自动有了。当然,前提是你用xcode 8编译的,xcode7.3还不支持iOS10,打出来的包也没有。

      本文标题:iOS 10 Widget

      本文链接:https://www.haomeiwen.com/subject/ucoejttx.html