在 UIView 代码中创建的 UIGestureRecognizer 不起作用
UIGestureRecognizer created in UIView code not working
我有一个 UIStackView
的自定义子 class,里面有一些 UIImageViews
。我希望视图接受平移手势来跟踪在其表面上的缓慢滑动。当我在 Interface Builder 中配置 UIPanGestureRecognizer
时,它可以工作,但在代码中没有。这是 class 的缩写版本:
@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 惰性 var 使其初始化延迟到第一次使用和设置堆栈视图的框架时。喜欢
private lazy var panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
或
将 panRecognizer 的声明移动到 addGesture 调用之前的 initializeProperties() 方法。喜欢
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
addGestureRecognizer(panRecognizer)
编辑
原因是目标设置为 null,因此当您使用 "private let .." 初始化时它无法触发该方法。由于稍后会调用 init,并且不会为 CustomView 初始化对象。这是用 let(constant):
声明时的控制台日志
self.panRecognizer的打印说明:
;目标= <(action=singleFingerSwipe:, target=<(null) 0x0>)>>
但是当它的lazy var or declared in the method after init被调用时,CustomeView的实例被生成直到使用panRecognizer。控制台打印是:
self.panRecognizer.storage.some 的打印说明:
;目标= <(action=singleFingerSwipe:, target=)>>
在这里您可以看到目标已设置。
P.S。你可以用 debugger
检查一下
我有一个 UIStackView
的自定义子 class,里面有一些 UIImageViews
。我希望视图接受平移手势来跟踪在其表面上的缓慢滑动。当我在 Interface Builder 中配置 UIPanGestureRecognizer
时,它可以工作,但在代码中没有。这是 class 的缩写版本:
@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 惰性 var 使其初始化延迟到第一次使用和设置堆栈视图的框架时。喜欢
private lazy var panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
或 将 panRecognizer 的声明移动到 addGesture 调用之前的 initializeProperties() 方法。喜欢
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CustomView.singleFingerSwipe))
addGestureRecognizer(panRecognizer)
编辑
原因是目标设置为 null,因此当您使用 "private let .." 初始化时它无法触发该方法。由于稍后会调用 init,并且不会为 CustomView 初始化对象。这是用 let(constant):
声明时的控制台日志self.panRecognizer的打印说明: ;目标= <(action=singleFingerSwipe:, target=<(null) 0x0>)>>
但是当它的lazy var or declared in the method after init被调用时,CustomeView的实例被生成直到使用panRecognizer。控制台打印是:
self.panRecognizer.storage.some 的打印说明: ;目标= <(action=singleFingerSwipe:, target=)>>
在这里您可以看到目标已设置。
P.S。你可以用 debugger
检查一下