【问题标题】:UISwipeGestureRecognizer doesn't work on presented VC and viewUISwipeGestureRecognizer 不适用于呈现的 VC 和视图
【发布时间】:2020-04-12 17:23:57
【问题描述】:

层次结构:

  • MainVC 调用present(GameVC, animated: true, completion: nil)

    let vc = self.storyboard?.instantiateViewController(withIdentifier: "GameVC") as! GameVC self.present(vc, animated: true, completion: nil)

  • GameVC 具有覆盖整个 VC 的 GameViewUIView 的子类)

GameView初始化程序中,我有这段代码来配置滑动手势:

let leftGesture = UISwipeGestureRecognizer(target: self, action: #selector(leftSwipe))
leftGesture.direction = .left
self.addGestureRecognizer(leftGesture)

let rightGesture = UISwipeGestureRecognizer(target: self, action: #selector(rightSwipe))
rightGesture.direction = .right
self.addGestureRecognizer(rightGesture)

let downGesture = UISwipeGestureRecognizer(target: self, action: #selector(downSwipe))
downGesture.direction = .down
self.addGestureRecognizer(downGesture)

对应的选择器:

@objc func downSwipe() {
    //code
}

@objc func leftSwipe() {
    //code
}

@objc func rightSwipe() {
    //code
}

选择器没有被调用。但是,当我将 GameVC 设置为正在显示的初始 VC 时(通过将情节提要箭头拖到 GameVC 上),手势按预期工作。这让我认为调用 present() 可能'已经搞乱了手势操作的层次结构,但我不太确定。

【问题讨论】:

  • 什么是self?它不可能是游戏视图控制器,因为 VC 没有addGestureRecognizer 方法。 present(GameVC, animated: true, completion: nil) 不是真正的代码,因为 GameVC 似乎是一种类型。你能准确地展示你是如何展示这个 VC 的吗? “GameVC 的初始化器”是指init,还是viewDidLoad
  • 不能使用委托模式吗?函数在`GameVC`还是MainVC`?
  • 你在哪个初始化方法中有代码?试着把它放在viewDidLoad
  • @Sweeper 我的错,我的意思是 GameView 的初始化程序。我会更新我的问题。
  • @Sweeper 我没有详细说明我如何呈现GameVC,因为它按预期工作,但如果有帮助,我会在我的问题中添加代码。

标签: ios swift selector uiswipegesturerecognizer presentviewcontroller


【解决方案1】:

您必须表明您的手势可以通过提供相应的委托方法同时处理。

下面的演示代码可以使用上面的代码。使用 Xcode 11.4 / iOS 13.4 测试

class GameView: UIView {
}

// in Storyboard just empty view of above custom GameView
class GameVC: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let leftGesture = UISwipeGestureRecognizer(target: self, action: #selector(leftSwipe))
        leftGesture.direction = .left
        leftGesture.delegate = self
        self.view.addGestureRecognizer(leftGesture)

        let rightGesture = UISwipeGestureRecognizer(target: self, action: #selector(rightSwipe))
        rightGesture.direction = .right
        rightGesture.delegate = self
        self.view.addGestureRecognizer(rightGesture)

        let downGesture = UISwipeGestureRecognizer(target: self, action: #selector(downSwipe))
        downGesture.direction = .down
        downGesture.delegate = self
        self.view.addGestureRecognizer(downGesture)

    }

    // allows own view gestures to run with system originated simultaneously
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        true
    }

    @objc func downSwipe() {
        print(">> down swipe")
    }

    @objc func leftSwipe() {
        print(">> left swipe")
    }

    @objc func rightSwipe() {
        print(">> right swipe")
    }
}

// Initial VC, in storyboard contains only button linked to below showGame action
class ViewController: UIViewController {

    @IBAction func showGame(_ sender: Any) {
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "GameVC") as! GameVC
        self.present(vc, animated: true, completion: nil)
    }
}

【讨论】:

  • 感谢您的回答,但我在 GameView 中配置手势,而不是在 GameVC 中。
  • 其实我意识到我可以像你说的那样在GameVC中配置手势,然后调用GameView方法。非常感谢,这完美!出于好奇,为什么我需要添加gestureRecognizer 回调?
  • @Xcoder,因为新的模态演示 iOS 安装了自己的 UISwipeGestureRecognizer,所以它们会发生冲突。
  • 非常感谢!最后一个问题:有什么方法可以禁用 iOS 自己的滑动手势?
  • @Xcoder,添加func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool委托方法并在其中返回true。但是你有责任关闭呈现的控制器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-23
  • 2020-11-01
  • 2021-09-11
  • 1970-01-01
  • 1970-01-01
  • 2013-05-04
相关资源
最近更新 更多