代码之家  ›  专栏  ›  技术社区  ›  Dov

在UIView代码中创建的UIgestureRecognitor不工作

  •  2
  • Dov  · 技术社区  · 7 年前

    我有一个自定义子类 UIStackView 有一些 UIImageViews 在里面。我希望视图接受平移手势,以跟踪在其曲面上的缓慢滑动。配置时 UIPanGestureRecognizer 在Interface Builder中可以工作,但在代码中不能工作。以下是该课程的缩写版本:

    @IBDesignable
    class CustomView: UIStackView {
    
        private let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
    
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            initializeProperties()
        }
    
        required init(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            initializeProperties()
        }
    
        @IBAction
        private func singleFingerSwipe(_ sender: UIPanGestureRecognizer) {
            print("Panning...")
        }
    
        private func initializeProperties() {
            addGestureRecognizer(panRecognizer)
    
            for _ in 1...3 {
                let imageView = UIImageView(image: UIImage(named: "MyImage"))
                imageView.translatesAutoresizingMaskIntoConstraints = false
                imageView.isUserInteractionEnabled = true
    
                addArrangedSubview(imageView)
                imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor).isActive = true
                imageView.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true
            }
        }
    }
    

    当我在星图中四处滑动时,没有输出打印。但是,如果我将平移手势识别器放到IB中的视图上,并将其连接到同一个选择器上,它就可以正常工作。我错过了什么?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Vanita L.    7 年前

    使您的panRecognizer变为lazy var,以便其初始化延迟到第一次使用和设置堆栈视图帧时。喜欢

        private lazy var panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
    

    或 将panRecognizer的声明移到AddSpiration调用之前的initializeProperties()方法。喜欢

    let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
    addGestureRecognizer(panRecognizer)
    

    编辑

    原因是当您使用“private let..”初始化时,目标设置为null,因此无法激发方法。因为init稍后被调用,并且没有为CustomView初始化对象。以下是使用let(常量)声明时的控制台日志:

    打印自我描述。装甲识别器: ; 目标=<(操作=singleFingerSwipe:,目标=<(null)0x0>)&燃气轮机&燃气轮机;

    但是,当调用init后在方法中声明其惰性var或时,CustomeView的实例将一直生成,直到使用panRecognizer为止。控制台打印为:

    打印自我描述。装甲识别器。存储一些: ; 目标=<(操作=单指滑动:,目标=)>&燃气轮机;

    在这里您可以看到目标已设定。

    P、 您可以使用调试器进行检查