首页 > 解决方案 > 在 UIViewControllers 之间传递 UILongPressGestureRecognizer

问题描述

我已经在 SO 和其他在线地方四处查看,但还没有找到解决方案。我在一个视图控制器上有一个 UILongPressGestureRecognizer,它在 UIView 上执行动画然后呈现另一个视图控制器(如果用户在动画期间没有移动手指)。当用户抬起手指时,我想关闭第二个视图控制器,但我遇到了麻烦。

我目前的方法是向第二个视图控制器添加另一个 UILongPressGestureRecognizer 并在其状态为 .ended 时关闭视图控制器;但是我不知道如何将两个手势识别器联系在一起,以便我可以在一个视图控制器中开始触摸并在另一个视图控制器中结束。

我在下面附上了相关代码

在第一个视图控制器中

   @objc private func pinAnimation(sender: UILongPressGestureRecognizer) {
    if let headerView = projectView.projectCollectionView.supplementaryView(forElementKind: UICollectionElementKindSectionHeader, at: IndexPath(row: 0, section: 0)) as? ProjectHeaderView {

        switch sender.state {
        case .began:
            let frame = headerView.pinButton.frame
            UIView.setAnimationCurve(.linear)

            UIView.animate(withDuration: 1, animations: {
                headerView.pinProgressView.frame = frame
            }, completion: { (_) in
                if (headerView.pinProgressView.frame == headerView.pinButton.frame) {
                    let notification = UINotificationFeedbackGenerator()
                    notification.notificationOccurred(.success)
                    let homeVC = HomeViewController()
                    self.present(homeVC, animated: true, completion: {

                        homeVC.longPress(sender)

                        let height = headerView.pinButton.frame.height
                        let minX = headerView.pinButton.frame.minX
                        let minY = headerView.pinButton.frame.minY
                        headerView.pinProgressView.frame = CGRect(x: minX, y: minY, width: 0, height: height)
                    })
                }
            })

        case .ended:
            //cancel current animation
            let height = headerView.pinProgressView.frame.height
            let minX = headerView.pinProgressView.frame.minX
            let minY = headerView.pinProgressView.frame.minY
            UIView.setAnimationCurve(.linear)
            UIView.animate(withDuration: 0.5) {
                headerView.pinProgressView.frame = CGRect(x: minX, y: minY, width: 0, height: height)
            }
        default:
            break
        }
    }
}

在第二个视图控制器中

override func viewDidLoad() {
    super.viewDidLoad()
    let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPress(_:)))
    view.addGestureRecognizer(longPressRecognizer)
}

@objc func longPress(_ sender: UILongPressGestureRecognizer) {
    switch sender.state {
    case .ended:
        self.dismiss(animated: true, completion: nil)
    default:
        break
    }
}

任何帮助/指导将不胜感激!

标签: iosswiftuiviewcontrolleruilongpressgesturerecogni

解决方案


我建议您使用委托模式:

为您的第一个 ViewController 创建委托

protocol FirstViewControllerDelegate {
    func longPressEnded() 
}

然后将delegate变量添加到您的第一个 ViewController

class FirstViewController {
    var delegate: FirstViewControllerDelegate?
    ...
}

长按结束时委托的下一个调用方法

@objc private func pinAnimation(sender: UILongPressGestureRecognizer) {
    ...
    switch sender.state {
    case .began:
        ...
    case .ended:
        ...
        delegate?.longPressEnded()
    default:
        break
    }
}

之后,当您呈现第二个 ViewController 时,将第一个 ViewController 设置delegatehomeVC

let homeVC = HomeViewController()
self.delegate = homeVC

然后将此委托实现到第二个 ViewController 并定义长按结束时应该发生的情况

class HomeViewController: UIViewController, FirstViewControllerDelegate {
    ...
    func longPressEnded() {
        dismiss(animated: true, completion: nil)
    }
}

推荐阅读