UIGestureRecognizer没有向其他类发送动作

时间:2018-06-09 18:05:16

标签: ios swift uitapgesturerecognizer

我试图将UIView类上的UIGestureRecognizer的动作发送到其父视图控制器。

HomeViewController包含一个包含多个(5)OperationViews的视图。

OperationView扩展了UIView,看起来像这样:

class OperationView: UIView {
    override func awakeFromNib() {
        super.awakeFromNib()

        // OperationView is on a view that has HomeViewController as it's controller in StoryBoard
        let swipeGestureRecognizer = UISwipeGestureRecognizer(target: HomeViewController.self(), action: #selector(HomeViewController.operatorWasSwiped(_:)))
        swipeGestureRecognizer.direction = .left

        let tapGestureRecognizer = UITapGestureRecognizer(target: HomeViewController.self(), action: #selector(HomeViewController.operatorWasSwiped(_:)))

        self.addGestureRecognizer(swipeGestureRecognizer)
        self.addGestureRecognizer(tapGestureRecognizer)
    }

在HomeViewController中我有这个函数应该由UIGestureRecognizers调用:

@objc func operatorWasSwiped(_ sender : UIGestureRecognizer) {
    if (sender.isKind(of: UITapGestureRecognizer.self)) { print("Tapped") }
    else { print("Swiped") }

    self.performSegue(withIdentifier: "segue1", sender: nil)
}

但是,我什么都搞定了。甚至不是错误。

我尝试在HomeViewController上使用IBOutlet将UIGestureRecognizer添加到每个OperationView中:

view1.swipeGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))
view2.swipeGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))
view3.swipeGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))
view4.swipeGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))
view5.swipeGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))

view1.tapGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))
view2.tapGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))
view3.tapGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))
view4.tapGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))
view5.tapGestureRecognizer?.addTarget(self, action: #selector(operatorWasSwiped(_ :)))

view1.addGestureRecognizer(view1.swipeGestureRecognizer!)
view2.addGestureRecognizer(view2.swipeGestureRecognizer!)
view3.addGestureRecognizer(view3.swipeGestureRecognizer!)
view4.addGestureRecognizer(view4.swipeGestureRecognizer!)
view.addGestureRecognizer(view5.swipeGestureRecognizer!)

view1.addGestureRecognizer(view1.tapGestureRecognizer!)
view2.addGestureRecognizer(view2.tapGestureRecognizer!)
view3.addGestureRecognizer(view3.tapGestureRecognizer!)
view4.addGestureRecognizer(view4.tapGestureRecognizer!)
view5.addGestureRecognizer(view5.tapGestureRecognizer!)

我已添加的地方:

var swipeGestureRecognizer: UISwipeGestureRecognizer?
var tapGestureRecognizer: UITapGestureRecognizer?

为OperationView

的类变量

这是有效的,但它远非优雅(想象一下,如果我必须添加另一个视图......有点击败我之前的抽象点)

任何想法发生了什么?或者我错过了什么?

我使用 Swift 4 Xcode 9

1 个答案:

答案 0 :(得分:2)

您正在方法内创建该手势,并且在调用该函数时手势可能只存在于该范围内。所以在使用它之前技术上正在消失。因此,在视图存在的同时,可以在方法之外创建该手势的实例。如果这是有道理的。

更新:从评论中指出,我们确实需要父viewController的当前引用。

这样做怎么样..

class OperationView: UIView {

let swipeGestureRecognizer = UISwipeGestureRecognizer()
let tapGestureRecognizer = UITapGestureRecognizer()

override func awakeFromNib() {
    super.awakeFromNib()

    if let parentViewController = parentViewController {
    swipeGestureRecognizer.addTarget(parentViewController, action: #selector(HomeViewController.operatorWasSwiped(_:)))
    swipeGestureRecognizer.direction = .left

    tapGestureRecognizer.addTarget(parentViewController, action: #selector(HomeViewController.operatorWasSwiped(_:)))

    self.addGestureRecognizer(swipeGestureRecognizer)
    self.addGestureRecognizer(tapGestureRecognizer)
    }

   }
}

extension UIView {

var parentViewController: UIViewController? {
    var parentResponder: UIResponder? = self

    while parentResponder != nil {
        parentResponder = parentResponder!.next

        if let viewController = parentResponder as? UIViewController {
            return viewController
        }
    }
    return nil
   }
}