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

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

发布了148 篇原创文章 · 获赞 16 · 访问量 46万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览