在Swift中使用TapGestures
Swift的上一个主要更新的一部分已经发布了许多重大改进。
Swift越来越大,我认为它所采取的方向确实很有希望。
另一方面,确实某些苹果API尚不希望人们利用Swift的所有这些新功能来获得最理想的接口。
如果您在tvOS项目中工作,那么您将不得不经常使用其中之一,那就是UITapGesturesRecognizer,这是为Siri Remote创建自定义手势的一种非常常见的方式。
更具体地说,我说的是为他们设置允许的触摸和按动类型的方式。
让手势= UITapGestureRecognizer(目标:自我,行动:#选择器(触发))
手势.allowedPressTypes = [NSNumber(值:UIPressType.menu.rawValue)]
手势.allowedTouchTypes = [NSNumber(value:UITouchType.indirect.rawValue)]
view.addGestureRecognizer(手势)
之前的代码是用Swift 3编写的,但是您可以在下面的内容中找到最近几年的发展:
// Objective-C:
手势.allowedPressTypes = @ [@ UIPressTypeMenu];
gesture.allowedTouchTypes = @ [@ UITouchTypeIndirect];
// Swift 2:
pose.allowedPressTypes = [UIPressType.Menu.rawValue]
pose.allowedTouchTypes = [UITouchType.Indirect.rawValue]
// Swift 3:
gesture.allowedPressTypes = [NSNumber(值:UIPressType.menu.rawValue)]
gesture.allowedTouchTypes = [NSNumber(值:UITouchType.indirect.rawValue)]
如您所见,每次迭代都使此代码变得越来越难读,从而增加了从NSNumber的演变继承而来的冗余冗长性。
几天前,由于我们正在将Zattoo迁移到Swift 3,我与同事Chris Goldsby先生谈到了这个问题。
而且…他给了我一个好主意。 实际上,获得像克里斯先生所希望的那样清晰易读的界面并不难。
毕竟,这两个属性只是NSNumbers的数组。 创建它们应该不难吗? 我们需要做的就是扩展功能,以便为不同的按键和触摸类型创建一组预定义的NSNumber。
扩展名NSNumber {
静态var菜单:NSNumber {
返回NSNumber(pressType:.menu)
}
静态var playPause:NSNumber {
返回NSNumber(pressType:.playPause)
}
静态var选择:NSNumber {
返回NSNumber(pressType:.select)
}
静态var upArrow:NSNumber {
返回NSNumber(pressType:.upArrow)
}
静态var downArrow:NSNumber {
返回NSNumber(pressType:.downArrow)
}
静态var leftArrow:NSNumber {
返回NSNumber(pressType:.leftArrow)
}
静态var rightArrow:NSNumber {
返回NSNumber(pressType:.rightArrow)
}
// MARK:-私人
私人便利init(pressType:UIPressType){
self.init(integerLiteral:pressType.rawValue)
}
}
扩展名NSNumber {
静态var直接:NSNumber {
返回NSNumber(touchType:.direct)
}
静态var间接:NSNumber {
返回NSNumber(touchType:.indirect)
}
// MARK:-私人
私人便利init(touchType:UITouchType){
self.init(integerLiteral:touchType.rawValue)
}
}
仅此而已…我们已经可以以更加可读的方式定义手势识别器:
让手势= UITapGestureRecognizer(目标:自我,动作:.upDownGestureWasTriggered)
pose.allowedPressTypes = [.upArrow,.downArrow]
pose.allowedTouchTypes = [.indirect]
view.addGestureRecognizer(手势)
{关闭,所有事情!!! }
好吧…实际上还不是全部…
很抱歉,但是我目前还无法完成本篇文章,谈论使UITapGestureRecognizers更具可读性,同时最后提供与Selectors配合使用的界面。
选择器是许多Apple API提供的出色接口,并且功能强大。
但是事实是选择器来自目标C,并利用objc运行时与动态调度一起工作。 我非常确定,它们将在不久的将来被闭包取代。
好的方面是,仅需一点点创意和可折叠性,我们就可以从Selectors中获得更快速的界面。
最后一堂TapGestureRecognizer:UITapGestureRecognizer {
私人让回调:()->无效
公共初始化(allowedPressTypes:[NSNumber] = [],allowedTouchTypes:[NSNumber] = [.indirect],回调:@escaping()-> Void){
self.callback =回调
super.init(目标:无,动作:无)
self.allowedPressTypes = allowedPressTypes
self.allowedTouchTypes = allowedTouchTypes
addTarget(self,action:#selector(invokeCallback))
}
// MARK:—私人
@objc private func invokeCallback(){
打回来()
}
}
仅此而已(再次)。 我们已经可以以更加可读和快速的方式定义手势识别器:
让手势= TapGestureRecognizer(allowedPressTypes:[.menu]){
//按下菜单键
}
view.addGestureRecognizer(手势)
结论
Apple可能(并希望)很快会给仍然需要它的那些API带来所有的爱和温柔,但是与此同时,它们是创造力的好借口,因此获得了更具可读性的代码……别害羞! !!