我目前在 Swift 开发的 iOS 应用程序中的自定义 UIView 类中面临 UITapGestureRecognizer 的问题。尽管我确实按照惯例设置了手势识别器,但它似乎根本不响应点击。以下是我的代码设置的相关部分:
视图控制器
class myViewController : ViewController {
init() {
super.init(nibName: nil, bundle: nil)
self.view.addSubview(self.myView)
self.myView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
self.myView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var myView : MyCustomView = {
let view = MyCustomView(frame: CGRect(x: 0, y: 0, width: 476.0, height: 398.0))
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
}
自定义视图
class MyCustomView : UIView {
override init(frame: CGRect) {
super.init(frame: frame)
self.widthAnchor.constraint(equalToConstant: frame.width).isActive = true
self.heightAnchor.constraint(equalToConstant: frame.height).isActive = true
self.mView.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
self.mView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private lazy var mView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = UIColor.init(hexString: "#EDEEEF")
view.isUserInteractionEnabled = true
let gesture = UITapGestureRecognizer(target: self, action: #selector(tappedDropDown))
view.addGestureRecognizer(gesture)
return view
}()
@objc func tappedDropDown(sender : UITapGestureRecognizer){
print("Tapped")
}
}
This也与此类似,但我无法理解我的情况发生了什么。我已经检查过以确保 isUserInteractionEnabled 设置为 true,并且没有覆盖 mView 的视图可以拦截触摸。
示例代码存在许多问题,会导致其停止工作,有些问题甚至会导致编译停止(未终止的字符串文字、尝试设置自动布局 (AL) 约束而不将 TAMIC 设置为 false 等)。
但我认为*停止点击手势工作的问题是布局代码是帧大小和 AL 约束的混合,并且它没有按照您认为的方式布局,这意味着自定义视图的子视图不是也没有收到回应的手势。
更改布局代码,使其全部为 AL,使点击手势正常工作,而无需对手势识别器或其操作方法进行任何更改。
我假设你想要的布局是带有子视图(你的
CustomView
)的VC视图,而子视图又拥有自己的子视图(你的mView
,下面我将其重命名为subView
以使其更清晰) ),在三层金字塔类型的堆栈中。
我在上面说“思考”是因为我可能在修复布局代码时纠正了一些其他错误。我只更正了编译并提供工作 UI 所需的代码。我没有故意解决任何其他问题,因为它们与问题无关。
下面的代码的工作原理是,它布置了三个视图(VC 的视图、
myView
(a CustomView
)和 CustomView 的 subview
,并将 tapGestureRecogniser
添加到 subView
。gestureRecogniser 会触发其点击时的选择器方法。它可能不会按照您想要的方式布局,因为很难告诉您想要实现的布局,但它确实证明了gestureRecogniser按预期工作。
class myViewController : UIViewController {
lazy var myView : MyCustomView = {MyCustomView(frame: .zero)}()
init() {
super.init(nibName: nil, bundle: nil)
view.heightAnchor.constraint(equalToConstant: 600).isActive = true
view.addSubview(myView)
myView.topAnchor.constraint(equalTo: view.topAnchor, constant: 50).isActive = true
myView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50).isActive = true
myView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50).isActive = true
myView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MyCustomView : UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .systemOrange
translatesAutoresizingMaskIntoConstraints = false
addSubview(subView)
subView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -50).isActive = true
subView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -50).isActive = true
subView.topAnchor.constraint(equalTo: topAnchor, constant: 50).isActive = true
subView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -50).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private lazy var subView: UIView = {
let view = UIView()
view.backgroundColor = .systemBlue
view.translatesAutoresizingMaskIntoConstraints = false
view.isUserInteractionEnabled = true
let gesture = UITapGestureRecognizer(target: self, action: #selector(tappedDropDown))
view.addGestureRecognizer(gesture)
return view
}()
@objc func tappedDropDown(sender : UITapGestureRecognizer){
print("Tapped")
}
}
我认为问题在于你的函数在 ViewController 之外运行。只需执行以下操作:
class myViewController : ViewController {
@objc func tappedDropDown(sender : UITapGestureRecognizer){
print("Tapped")
}
init() {
super.init(nibName: nil, bundle: nil)
self.view.addSubview(self.myView)
self.myView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
self.myView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var myView : MyCustomView = {
let view = MyCustomView(frame: CGRect(x: 0, y: 0, width: 476.0, height: 398.0))
view.translatesAutoresizingMaskIntoConstraints = false
let gesture = UITapGestureRecognizer(target: self, action: #selector(tappedDropDown))
view.addGestureRecognizer(gesture)
return view
}()
}
并且,从您的自定义类中删除我在此处添加的行。