zoukankan      html  css  js  c++  java
  • 在iOS9 中使用3D Touch

    iOS9提供了四类API( Home Screen Quick ActionUIKit Peek & PopWebView Peek & PopUITouch Force Properties )用于操作3D Touch。不过无论使用哪一种API,首先需要做的事情是检查3D Touch是否可用。

    检测是否支持3D Touch

    在iOS9中提供如下的接口用于检查设备是否支持3D Touch:

    @property(nonatomic, readonly) UIForceTouchCapability forceTouchCapability;

    其中 UIForceTouchCapability 是一个枚举类型,具体的描述情况如下:

    • UIForceTouchCapability
      • UIForceTouchCapabilityUnknown //3D Touch检测失败
      • UIForceTouchCapabilityUnavailable //3D Touch不可用
      • UIForceTouchCapabilityAvailable //3D Touch可用

    这3个枚举值就是我们来判断设备是否开启3D Touch功能,可以在UIViewController生命周期的viewWillAppear中做如下判断:

    if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
      //do something
    }

    当然在生命周期内,如果用户有意修改了设备的3D Touch功能,我们还有一个地方来重新检测:

    - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
      //do something
    }

    Home Screen Quick Action

    创建Quick Action有两种方式:静态和动态

    ①以静态方式创建

    静态创建的方式是在Info.plist文件中进行声明的

    <key>UIApplicationShortcutItems</key>
    <array>
     <dict>
            <key>UIApplicationShortcutItemIconType</key>
            <string>UIApplicationShortcutIconTypeShare</string>
            <key>UIApplicationShortcutItemTitle</key>
            <string>分享</string>
            <key>UIApplicationShortcutItemType</key>
            <string>UITouchText.share</string>
            <key>UIApplicationShortcutItemUserInfo</key>
            <dict>
                <key>key1</key>
                <string>value1</string>
            </dict>
        </dict>
      <dict>
          <key>UIApplicationShortcutItemType</key>
          <string>com.devzeng.about</string>
          <key>UIApplicationShortcutItemTitle</key>
          <string>关于我们</string>
          <key>UIApplicationShortcutItemSubtitle</key>
          <string>这是关于我们</string>
          <key>UIApplicationShortcutItemIconFile</key>
          <string>icon_about.png</string>
          <key>UIApplicationShortcutItemUserInfo</key>
          <dict>
              <key>scheme</key>
              <string>devzeng://about</string>
          </dict>
      </dict>
    </array>

    ②以动态方式创建

    动态创建是在程序初始化的时候用代码动态添加。 UIApplication 对象多了一个支持快捷方式的数组(shortcutItems), 如果需要增加快捷方式,可以赋值给shortcutItems属性。

    在方法中 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

     UIApplicationShortcutIcon *icon = [UIApplicationShortcutIcon iconWithTemplateImageName:@"1234"];
        UIApplicationShortcutItem *item = [[UIApplicationShortcutItem alloc] initWithType:@"search22"
                                                                           localizedTitle:@"search22"
                                                                        localizedSubtitle:@"0abc"
                                                                                     icon:icon
                                                                                 userInfo:nil];
        application.shortcutItems = @[item];

    说明:

    1)系统限制每个App最多能够显示4个Action Item,其中包括静态方式和动态方式进行创建的;

    2)如果静态和动态方式同时使用的时候,给UIApplication的shortcutItems赋值的时候不会覆盖

    3)注,定义的图标 是35x35 的单色图标

    当app在后台的时候UIApplication提供了一个回调方法,如下

    - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem
      completionHandler:(void(^)(BOOL succeeded))completionHandler{
        //判断先前我们设置的唯一标识
        if([shortcutItem.type isEqualToString:@"UITouchText.share"]){
            NSArray *arr = @[@"hello 3D Touch"];
            UIActivityViewController *vc = [[UIActivityViewController alloc]initWithActivityItems:arr applicationActivities:nil];
            //设置当前的VC 为rootVC
            [self.window.rootViewController presentViewController:vc animated:YES completion:^{
            }];
        }
        else if ([shortcutItem.type isEqualToString:@"UITouchText.search"])
        {
            UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"好想你" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:@"sure", nil];
            [alertView show];
        }
        else if ([shortcutItem.type isEqualToString:@"UITouchText.look"])
        {
            UIActionSheet *sheet = [[UIActionSheet alloc]initWithTitle:@"温馨提示" delegate:nil cancelButtonTitle:@"cancel" destructiveButtonTitle:@"删除" otherButtonTitles:@"更多", nil];
            [sheet showInView:self.window];
        }
        else if ([shortcutItem.type isEqualToString:@"UITouchText.compose"])
        {
            NSLog(@"UITouchText.compose");
        }
    }

     我们依据这个回调中的shortcutItem的type和userinfo来做出不同的事件处理,而最后的completionHandler在API的说明中我们看到当应用并非在后台,而是直接重新开进程的时候,直接返回No,那么这个时候,我们的回调会放在

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    UIApplication又给我们一个从launchOptions中获取这个shortcutItem的key(UIApplicationLaunchOptionsShortcutItemKey)

    UIApplicationShortcutItem *item = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];
    //根据不同的Action响应不同的事件

    Peek and Pop(预览和详阅)

    如同使用放大镜拉近视角,预览(Peek)内容(照片、视频)让你可以获得更多信息而不需要加载完整内容。

    Instagram首先将Peek功能添加到了小图片和视频上。

    Peek(预 览)和Pop(详阅)相关的API为UIViewControllerPreviewingDelegate,它通过view来注册。在 Instagram中,我们只将其注册到可以接受到touch事件的controller的view上。当3D touch事件发生时,delegate来检测view中的哪个对象被点击。

    如果delegate判断有Peek(预览)动作发生,它仍需要处理两件事情:1. 设置预览动作发生的view的rect;2. 返回展示的viewcontroller。

    当3D touch发生时,会传递给你context信息,包含源view和点击发生的point。自定义的delegate需要通过这个point映射到一个view,然后查找到需要预览的数据。

    大多数的Instagram功能基于UICollectionView和UITableView实现。这两者在数据和UI间对应方面都有不错的API支持。

    - (UIViewController *)previewingContext:(id)previewingContext viewControllerForLocation:(CGPoint)location {
      UICollectionView *collectionView = (UICollectionView *)[previewingContext sourceView];
      NSIndexPath *indexPath = [collectionView indexPathForItemAtPoint:location];
         
        if (indexPath) {
        IGPostCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
        [previewingContext setSourceRect:cell.frame];
         
        IGPost *post = self.feedController.posts[indexPath.row];
        IGThumbnailPreviewController *controller = [[IGThumbnailPreviewController alloc] initWithPost:post];
          return controller;
      }
       
      // no peek
      return nil;
    }

    将预览相关的API和现有的view和功能结合后,查看Instagram照片和视频变的异常简单

    我们为header和comment中的用户名添加了查看信息的功能。用来预览用户信息的delegate和显示照片/视频的实现类似:

    • 使用3D touch点击的location和查找到的index path找到对应的cell。

    • 将点击的point关联转换到cell中的textview上。

    • 通过该point获取到text view中的attributed string的属性。

    • 如果找到了用户名称的属性,则返回IGUserPreviewController。

    将这些实现串起来,看起来就像这样:

    混合内容展示

    Instagram中的activity feed功能包含了用户的tag和缩略图。我们之前分别创建过UIViewControllerPreviewingDelegate的对象,用来显示这两种内容。这里我们需要把这些组合在一起。

    拷贝已有代码到新的delegate中的做法并不明智。我们选择使用composition模式来组合profile和post展示的delegate代码,这样创建一个新的对象,只需要传递touch 事件即可。

    @interface IGUserThumbnailPreviewingHandler : NSObject
    @property (nonatomic, strong) IGUserPreviewingHandler *userDelegate;
    @property (nonatomic, strong) IGFeedThumbnailPreviewingHandler *thumbnailDelegate;
    @end
     
    - (UIViewController *)previewingContext:(idUIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
        id controller = [self.thumbnailDelegate previewingContext:previewingContext viewControllerForLocation:location];
        if (!controller) {
            controller = [self.userDelegate previewingContext:previewingContext viewControllerForLocation:location];
        }
        return controller;
    }

    用来显示预览的controller只是UIViewController的子类,在某些特别属性上有所不同。

    一开始,controller完全无法交互,你无法在上面点击按钮或添加自定义手势。这里我们需要提供遵循UIPreviewActionItem协议的对象组成的数组。在Instagram中,我们只用UIPreviewActions。

    这些功能看起来很像UIAlertController的action item。

    在整个Instagram程序中,我们只在需要的时候加载数据,并缓存以备以后使用。这样做既节省了网络等待的时间,又不会浪费用户的带宽。

    有 时,当预览用户profile时,我们获取的数据还不足以用来显示最新照片或关注者数量。预览用的view controller仍然会调用viewDidLoad, viewWillAppear:和其他UIViewController事件。在其中可以获取网络数据并更新UI。

    最后,我们发现可以通过修改controller的preferredContentSize来调整预览视图的大小,即便是controller已经展示了,这样的改变仍可生效。不过,这个属性无法作用于动画中。

     ios 3D Touch功能的实现

    参考:http://git.devzeng.com/blog/ios9-3d-touch.html?utm_source=tuicool&utm_medium=referral

    http://engineering.instagram.com/posts/465414923641286/lessons-learned-with-3D-touch

    http://www.cocoachina.com/ios/20151110/14129.html

  • 相关阅读:
    教你认识Git
    jmeter跨线程组传递token
    win10企业版激活步骤
    jmeter录制浏览器Https请求
    win10程序无法正常启动0xc0000142
    PPT页面切换动画
    PPT页面动画制作
    查询一门成绩高于另一门课程的学生信息
    MongoDB固定集合-capped collection
    CoronaSDK场景管理库:Composer library (中)
  • 原文地址:https://www.cnblogs.com/dhui69/p/5413839.html
Copyright © 2011-2022 走看看