7

我刚开始在我的应用程序中添加基本的 3D Touch 功能,第一次添加它的尝试进展顺利,看起来相当简单。

然而,我想知道是否有一种方法可以检测到偷看已经完成,并且没有进入流行。

UIViewControllerPreviewingDelegate 方法可以很好地告诉您请求查看或弹出,但我没有看到一种方法可以告诉您查看已经结束并且没有进入弹出状态。

Peeked ViewController 是否有办法知道它现在被偷看并消失,因为我想这已经足够了。基本上我有一个segue,它通常会在进入视图时创建一些东西,如果我窥视它,如果用户选择只是结束窥视而不弹出,则需要撤消它。目前我似乎无法查看检测这种情况的好方法,以便能够执行所需的清理。

干杯

4

2 回答 2

15

当您使用 注册预览时registerForPreviewingWithDelegate(),这将返回一个符合UIViewControllerPreviewing协议的上下文。该协议包含对用于窥视/弹出的手势识别器的引用,称为previewingGestureRecognizerForFailureRelationship. 它旨在在可能同时识别其他手势识别器时使用,但您也可以添加自己的对象作为目标以观察变化。

现在,当你偷看时,这个手势识别器的状态将是.Changed。当您释放而不弹出时,状态将变为.Ended. 当您弹出时,状态将更改为.Cancelled(我实际上希望这是另一种方式,但至少我们可以分辨出区别)。重要的是,在调用 peeked 视图控制器之前,此状态会发生变化viewDidDisappear,因此您可以及时调整标志。

于 2015-11-18T11:00:51.413 回答
1

我在我的应用程序中遇到了同样的问题,我需要知道视图控制器何时启动和停止被偷看,并提出以下问题。

为了监控偷看的生命周期,您可以跟踪被偷看的视图控制器的生命周期,从创建的视图控制器开始,previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController到它的viewDidDisappear().

我在被窥视的视图控制器中创建了一个回调处理程序PeekingViewController

var viewDidDisappearHandler: (()->())? = nil

并将其放在PeekingViewController'sviewDidDisappear中:

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    viewDidDisappearHandler?()
}

回到OriginalViewcontroller我们正在窥视的PeekingViewController地方,保持对被窥视的视图控制器实例的引用,如下所示:

weak var peekingViewController: PeekingViewController?

func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
    self.peekingViewController = PeekingViewController()
    return peekingViewController
}

然后,您可以通过在实例中填写 didSet 来观察对被窥视的视图控制器的弱引用的变化,peekingViewController如下所示:

weak private var peekingViewController: PeekingViewController? {
    didSet {
        peekingViewController?.viewDidDisappearHandler = { [weak self] in
            self?.peekingViewController = nil
        }
        if peekingViewController == nil { // Peek ended
            handlePeekEnded()
        } else { // Peek began
            handlePeekBegan()
        }
    }
}

注意:如果执行并取消了一个峰值,则会触发此逻辑,但如果执行了一个峰值,则segue完成,然后PeekingViewController弹出新呈现的。

如果您需要关于取消窥视的逻辑,通过不完整的窥视触发,而不是完整的峰值然后解除,您可以通过以下方式实现:

包括一个新的布尔值OriginalViewController来跟踪视图控制器是否被完全推送(OriginalViewController'sviewDidDisappear将在完全推送时触发,但不会在偷看时触发),并检查peekingViewController's中的布尔值didSet,以确定是否应采取任何操作,并设置peekingViewController为零。OriginalViewController_viewWillAppear

于 2018-09-20T05:41:48.217 回答