检测何时取消 3D Touch Peek 和 Pop View
Posted
技术标签:
【中文标题】检测何时取消 3D Touch Peek 和 Pop View【英文标题】:Detect when 3D Touch Peek and Pop View is Canceled 【发布时间】:2018-02-27 14:35:38 【问题描述】:我有一个启用了 3D Touch Peek and Pop 的 UITableView
。我希望能够检测到用户何时偷看视图以及何时用户停止偷看视图而不弹出。我知道previewingGestureRecognizerForFailureRelationship 存在。我试过这样使用它:
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
// Here's where I add the gesture
let gesture = previewingContext.previewingGestureRecognizerForFailureRelationship
gesture.addObserver(self, forKeyPath: "state", options: .new, context: nil)
let sb = UIStoryboard(name: "Main", bundle: nil)
let detailVC = sb.instantiateViewController(withIdentifier: "SongPreviewViewController") as? SongPreviewViewController
return detailVC
然后我添加
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
// can recognize peeking and canceling commit
if let object = object
if keyPath == "state"
let newValue = (change![NSKeyValueChangeKey.newKey]! as AnyObject).integerValue
let state = UIGestureRecognizerState(rawValue: newValue!)!
switch state
case .possible:
print("switch - possible")
case .began:
print("switch - began")
case .changed:
print("switch - changed")
case .ended:
print("switch - ended")
case .cancelled:
print("switch - cancelled")
case .failed:
print("switch - failed")
但每次查看视图开始时,都会调用.ended
。有谁知道如何正确地做到这一点? Here's the reference I used for this code.感谢您的帮助!
【问题讨论】:
【参考方案1】:UITapGestureRecognizer 仅在手势状态为 UIGestureRecognizerStateEnded 时触发,如下链接所述:
About messages from UITapGestureRecognizer
所有手势识别器都在可能状态 (possible) 开始一个多点触控序列。如果您希望获得最多两种状态:(.Possible) 和 (.end) 你可以试试这段代码(Xcode 9.2,swift 3.2,target 11.2)。
更改您的 addObserver 代码(添加更多选项):
gesture.addObserver(self, forKeyPath: "state", options: [.prior, .old, .new], context: nil)
在您的 observeValue 方法中获取旧值和新值,如下所示。它将调用 (.possible) 和 (.end) 状态:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
// can recognize peeking and canceling commit
if let object = object
if keyPath == "state"
var newValue:Int?
guard let change = change else return
let old = change[.oldKey] == nil || change[.oldKey] as? NSNull != nil ? "nil" : "\(change[.oldKey]!)"
let new = change[.newKey] == nil || change[.newKey] as? NSNull != nil ? "nil" : "\(change[.newKey]!)"
if change[.notificationIsPriorKey] as? Bool == true
newValue = (old as AnyObject).integerValue
else
newValue = (new as AnyObject).integerValue
let state = UIGestureRecognizerState(rawValue: newValue!)!
switch state
case .possible:
print("switch - possible")
case .began:
print("switch - began")
case .changed:
print("switch - changed")
case .ended:
print("switch - ended")
case .cancelled:
print("switch - cancelled")
case .failed:
print("switch - failed")
【讨论】:
【参考方案2】:还有另一个函数previewingContext(_:commit:)
用于告诉您它将提交。您可以使用它来设置一个属性,如果没有设置,您可以判断 3D Touch 动作没有“弹出”。 Documentation.
【讨论】:
以上是关于检测何时取消 3D Touch Peek 和 Pop View的主要内容,如果未能解决你的问题,请参考以下文章
如何实现 3D-Touch Peek-and-select?