IOS开发之 一起用Swift来玩一玩3D Touch

原创 2017年02月07日 14:45:51

Swift 2.3 IOS 8.0 XCode 8.0

添加入口标签

在这里只说下静态的好了,暂时还用不到动态的,e.g.

<key>UIApplicationShortcutItems</key>
<array>
    <dict>
        <key>UIApplicationShortcutItemType</key>
        <string>ReceiveMoney</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>当面收款</string>
        <key>UIApplicationShortcutItemIconFile</key>
        <string>short_icon_sk</string>
    </dict>
</array>

字段说明:

字段名 功能 是否必须 备注
UIApplicationShortcutItemType 这个键值设置一个快捷通道类型的字符串 必有项 我们可以监听该项的值来判断用户是从哪一个标签进入App的,该字段的值可以为空。
UIApplicationShortcutItemTitle 这个键值设置标签的标题 必有项 我们可以监听该项的值来判断用户是从哪一个标签进入App的
UIApplicationShortcutItemSubtitle 设置标签的副标题 可选项
UIApplicationShortcutItemIconType 设置标签的图标样式,系统提供了29中样式的图标,但大部分只能在9.1的系统上使用,只有少数可以在9.0的系统中使用,这一部分会在后边详细介绍 可选项
UIApplicationShortcutItemIconFile 设置自定义标签图片文件的路径 可选项
UIApplicationShortcutItemUserInfo 设置用户信息,是一个字典类型,可以用来传值 可选项

提示

UIApplicationShortcutItemIconFile存在的话,UIApplicationShortcutItemIconType就会失效

UIApplicationShortcutItemIconType的图标

这里写图片描述

很多人都只放出一个枚举值,我嘛~麻烦点,把所有的图标都从官网上下载下来,截了个图放上来

typedef NS_ENUM(NSInteger, UIApplicationShortcutIconType) {
    UIApplicationShortcutIconTypeCompose,
    UIApplicationShortcutIconTypePlay,
    UIApplicationShortcutIconTypePause,
    UIApplicationShortcutIconTypeAdd,
    UIApplicationShortcutIconTypeLocation,
    UIApplicationShortcutIconTypeSearch,
    UIApplicationShortcutIconTypeShare,
    UIApplicationShortcutIconTypeProhibit       NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeContact        NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeHome           NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeMarkLocation   NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeFavorite       NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeLove           NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeCloud          NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeInvitation     NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeConfirmation   NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeMail           NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeMessage        NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeDate           NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeTime           NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeCapturePhoto   NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeCaptureVideo   NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeTask           NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeTaskCompleted  NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeAlarm          NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeBookmark       NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeShuffle        NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeAudio          NS_ENUM_AVAILABLE_IOS(9_1),
    UIApplicationShortcutIconTypeUpdate         NS_ENUM_AVAILABLE_IOS(9_1)
} NS_ENUM_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED;

short_icon_sk是我自己的图片,因为上面的图标实在找不到合适的,这个时候,在手机上就可以看到了

e.g.
这里写图片描述

怎么样,还好吧。

检测App启动方式

启动方式

  1. 热启动,App已经打开,使用3D touch再次打开应用
  2. 冷启动,App关闭状态

不关是哪种启动方式,都会调用下面的方法

@available(iOS 9.0, *)
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
    // shortcutItem.type 就是 UIApplicationShortcutItemType 的值
    // TODO: 只要是3D touch 入口,都会触发到这里的
}

按道理,只要到这里就好了,根据shortcutItem.type的值跳转到制定的viewController就好了。问题就是要找到当前活动的viewController才可以,否则怎么跳转。

extension UIWindow {
    // 获取当前活动的控制器
    public var visibleViewController:UIViewController? {
        return UIWindow.getVisibleViewControllerFrom(self.rootViewController)
    }

    public static func getVisibleViewControllerFrom(vc:UIViewController?) -> UIViewController? {
        if let nc = vc as? UINavigationController {
            return UIWindow.getVisibleViewControllerFrom(nc.visibleViewController)
        } else if let tc = vc as? UITabBarController {
            return UIWindow.getVisibleViewControllerFrom(tc.selectedViewController)
        } else {
            if let pvc = vc?.presentedViewController {
                return UIWindow.getVisibleViewControllerFrom(pvc)
            } else {
                return vc
            }
        }
    }
}

这个问题解决了,那就跳呗。热启动状态下没问题。冷启动的时候就不行了。window!.visibleViewController == nil 了。尝试着延后点执行。放到applicationDidBecomeActive方法中

func applicationDidBecomeActive(application: UIApplication) {
    // TODO: 这里开始
}

applicationDidBecomeActive只要应用从后台激活就会调用,我们需要增加一个状态判断是否触发了3D touch

// 触发3D Touch的type
var activeFrom3Dtouch:ShortcutIdentifier?
// 3Dtouch的type
enum ShortcutIdentifier:String {
    // 当面收款
    case ReceiveMoney = "ReceiveMoney"
}
// 
@available(iOS 9.0, *)
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
    activeFrom3Dtouch = ShortcutIdentifier(rawValue: shortcutItem.type)
}

func applicationDidBecomeActive(application: UIApplication) {
    // 判断入口
    guard let touchType = activeFrom3Dtouch else {
        return
    }

    // TODO: 判断跳转操作

    // 清除,防止再次激活应用重复触发
    activeFrom3Dtouch = nil
}

看起来差不多了,运行了一下,冷启动还是不动。看了下微信、支付宝一类的应用,发现都是应用启动起来一会儿后才跳转。

然后 的然后,我也做了一个延迟,果然,冷启动也OK了

AppDelegate中的完整代码

// 触发3D Touch的type
var activeFrom3Dtouch:ShortcutIdentifier?
// 3Dtouch的type
enum ShortcutIdentifier:String {
    // 当面收款
    case ReceiveMoney = "ReceiveMoney"
}
// 
@available(iOS 9.0, *)
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
    activeFrom3Dtouch = ShortcutIdentifier(rawValue: shortcutItem.type)
}

func applicationDidBecomeActive(application: UIApplication) {
    // 判断入口
    guard let touchType = activeFrom3Dtouch else {
        return
    }

     // 分类处理
    if touchType == .ReceiveMoney {
        // 延时0.5就足够了
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
            // 获取活动的Controller
            guard let currentViewController = self.window?.visibleViewController else {
                return
            }

            // 不要重复打开付款页面
            guard !currentViewController.isKindOfClass(ReceiveMoneyViewController) else {
                return
            }

            let board = UIStoryboard(name: "MyAccount", bundle: nil)
            let viewController = board.instantiateViewControllerWithIdentifier("receiveMoneyViewController")

            // 判断是否模态
            if(currentViewController.navigationController == nil) {
                currentViewController.presentViewController(viewController, animated: true, completion: nil)
            } else {
                currentViewController.navigationController?.pushViewController(viewController, animated: true)
            }
        }
    }

    // 清除,防止再次激活应用重复触发
    activeFrom3Dtouch = nil
}

总结

做到这里基本上就可以用了,3D Touch本身并不复杂,但获取当前的viewController是比较麻烦的。在冷启动的时候,使用延时执行的方式获取到当前活动的viewController。

参考:

http://stackoverflow.com/questions/11637709/get-the-current-displaying-uiviewcontroller-on-the-screen-in-appdelegate-m

版权声明:本文为博主原创文章,然而你想怎么转就怎么转好了

IOS 实现3D Touch在tableView的简单应用(swift版)

之前记录过OC版实现3D Touch功能的小小演示,最近无事整整swift,也能弄一过swift版的3D Touoch。。。 上代码。 一、3D Touch重按主屏icon出现快捷标签有两种添...
  • u010277446
  • u010277446
  • 2016年06月02日 19:03
  • 4349

iOS 3D Touch 实现UITableViewCell 预览

效果图好丑. 测试手机iPhone6s , 也就是使用了新特性 3DTouch. 囧 不知道的以为会有多难.在开始之前UIViewControllerPreviewingDelegate // 签订...
  • sinat_30162391
  • sinat_30162391
  • 2016年05月22日 00:47
  • 3305

3DTouch Demo 从零构建3D Touch 教学

从0开始,详细实现3D Touch常用功能,满足日常需求,良心Demo
  • wxs0124
  • wxs0124
  • 2015年11月27日 10:27
  • 1342

3D Touch 的实现和系统分享功能

3D Touch其实就是快速进入指定app界面的一种方式。 下面和大家分享一下简单的实现 1、静态标签 静态标签是我们在项目的配置plist文件中配置的标签,在用户安装程序后就可以使用,并且排序...
  • yishengzhiai005
  • yishengzhiai005
  • 2016年12月07日 15:30
  • 1829

3DTouch综合教程OC+Swift4.0

  • 2017年10月12日 15:04
  • 73KB
  • 下载

iOS开发 Object-C 与 Swift 中的Touch ID开发 重磅出击3DTouch 仅限于6s或以上机型实用

iOS开发 Object-C 与 Swift 中的Touch ID开发 重磅出击3DTouch
  • Luck_Developer
  • Luck_Developer
  • 2016年03月07日 15:29
  • 787

iOS9新特性之(OC及Swift)实现3D Touch

在网上找了下资料,貌似很少的,只找到一篇简单介绍的  地址:http://www.jianshu.com/p/74fe6cbc542b 当然根据这篇文章的资料,很难做出这个有趣的功能,至少我是这么认...
  • sinat_34380438
  • sinat_34380438
  • 2016年09月08日 16:36
  • 306

iOS开发 Object-C 与 Swift 中的Touch ID开发 重磅出击3DTouch 仅限于6s或以上机型实用

iOS开发 Object-C 与 Swift 中的Touch ID开发 重磅出击3DTouch
  • Luck_Developer
  • Luck_Developer
  • 2016年03月07日 15:29
  • 787

3D touch 静态、动态设置及进入APP的跳转方式

申明Quick Action有两种方式:静态和动态 静态是在info.plist文件中申明,动态则是在代码中注册,系统支持两者同时存在。 -系统限制每个app最多显示4个快捷图标,包括静态和动态 静态...
  • y2888886
  • y2888886
  • 2016年11月29日 15:09
  • 727

3D-Touch快速启动APP,并push到指定VC以及无限压栈的问题

3D-Touch快速启动应用,并push到指定页面,我并不怎么用这个,昨天从朋友那听说无限压栈的问题,我才试了试,其实情况是这样的:以 企鹅 举例, 点击”扫一扫“,进入扫码页面,然后回到桌面,...
  • u010731949
  • u010731949
  • 2016年09月08日 15:28
  • 630
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IOS开发之 一起用Swift来玩一玩3D Touch
举报原因:
原因补充:

(最多只允许输入30个字)