我有一个UIStackView
的自定义子类,里面有一些UIImageViews
。我希望视图接受平移手势以跟踪其表面上的缓慢滑动。当我在Interface Builder中配置UIPanGestureRecognizer
时,它可以工作,但不能在代码中工作。这是该类的缩写版本:
@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
}
}
}
当我在星空视图内滑动时,没有输出打印。但是,如果我将Pan Gesture Recognizer放到IB中的视图上,并将其连接到同一选择器,则可以正常工作。我想念什么?
最佳答案
将panRecognizer设置为lazy var,以便将其初始化延迟到首次使用和设置堆栈视图的框架为止。喜欢
private lazy var panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
要么
在addGesture调用之前,将panRecognizer的声明移动到initializeProperties()方法。喜欢
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
addGestureRecognizer(panRecognizer)
编辑
原因是目标正在设置为null,因此当您使用“private let ..”进行初始化时,它无法激发该方法。由于稍后会调用init,因此不会为CustomView初始化对象。这是用let(constant)声明时的控制台日志:
self.panRecognizer的打印说明:
; target = )>>
但是,当其惰性变量或在init之后的方法中声明时,将生成CustomeView的实例,直到使用panRecognizer为止。控制台打印为:
self.panRecognizer.storage.some的打印说明:
; target = >
在这里您可以看到目标已设定。
附言您可以使用调试器进行检查