我有一个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中的视图上并将它连接到同一个选择器上,它就可以正常工作。我错过了什么?
答案 0 :(得分:3)
使你的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 =<(action = singleFingerSwipe:,target =<(null)0x0>)>>
但是当调用它的lazy var或在init之后的方法中声明时,生成CustomeView的实例直到使用panRecognizer时。控制台打印是:
打印self.panRecognizer.storage.some的说明: ; target =<(action = singleFingerSwipe:,target =)>>
在这里你可以看到目标已经设定。
P.S。您可以使用调试器检查相同的内容