Swift hitTest:point withEvent检测子视图
Swift hitTest:point withEvent to detect subview
我正在尝试使用 hitTest
检测子视图何时被点击。这是我的实现:
class MyViews:UIView {
override init (frame : CGRect) {
super.init(frame : frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
for subview in self.subviews.reversed() {
let subPoint = subview.convert(point, from:self);
if let result = subview.hitTest(subPoint, with:event) {
return result;
}
}
return nil
}
}
这是我添加子视图的方式:
override func viewDidLoad() {
super.viewDidLoad()
let gesture = UITapGestureRecognizer(target: self, action: #selector(doSomethingHere(_:)))
let blueView = MyViews(frame: CGRect(origin: CGPoint(x: 38.0, y: 231.0), size: CGSize(width: 335.0, height: 444.0)))
blueView.tag = 100
blueView.isUserInteractionEnabled = true
blueView.backgroundColor = .blue
blueView.addGestureRecognizer(gesture)
view.addSubview(blueView)
let grey = MyViews(frame: CGRect(origin: CGPoint(x: 38.0, y: 20.0 ), size: CGSize(width: 279, height: 203.0)))
grey.tag = 200
grey.backgroundColor = .gray
grey.isUserInteractionEnabled = true
grey.addGestureRecognizer(gesture)
blueView.addSubview(grey)
let white = MyViews(frame: CGRect(origin: CGPoint(x: 56.0 , y: 17.0 ), size: CGSize(width: 182.0, height: 92)))
white.tag = 300
white.isUserInteractionEnabled = true
white.addGestureRecognizer(gesture)
grey.addSubview(white)
let result = blueView.hitTest(CGPoint(x: 157.5, y: 149.0), with: nil)
print(result ?? "no result")
}
我正在模拟这条线上的触摸let result = blueView.hitTest(CGPoint(x: 157.5, y: 149.0), with: nil)
但是这个函数的响应:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
for subview in self.subviews.reversed() {
let subPoint = subview.convert(point, from:self);
if let result = subview.hitTest(subPoint, with:event) {
return result;
}
}
return nil
}
它总是为零。我不明白为什么它应该返回白色视图。
你们知道为什么这个函数没有返回正确的视图吗?
非常感谢你的帮助。
您的 hitTest 似乎从不检查该点是否在视图中。试一试:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// if there are subviews, step through them
// if the subview contains the point, call hitTest on the subview to see if the subview's subviews contain the point
// if they do, return the result,
// if they don't, return the subview that does contain the point.
for subview in self.subviews.reversed() {
let subPoint = subview.convert(point, from:self)
if subview.point(inside: subPoint, with: event) == true {
if let result = subview.hitTest(subPoint, with: event) {
return result
} else {
return subview
}
}
}
// none of the subviews contain the point,(or there are no subviews) does the current view contain the point?
// if yes, return self. otherwise, return nil
if self.point(inside: point, with: event) == true {
return self
} else {
return nil
}
}
我正在尝试使用 hitTest
检测子视图何时被点击。这是我的实现:
class MyViews:UIView {
override init (frame : CGRect) {
super.init(frame : frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
for subview in self.subviews.reversed() {
let subPoint = subview.convert(point, from:self);
if let result = subview.hitTest(subPoint, with:event) {
return result;
}
}
return nil
}
}
这是我添加子视图的方式:
override func viewDidLoad() {
super.viewDidLoad()
let gesture = UITapGestureRecognizer(target: self, action: #selector(doSomethingHere(_:)))
let blueView = MyViews(frame: CGRect(origin: CGPoint(x: 38.0, y: 231.0), size: CGSize(width: 335.0, height: 444.0)))
blueView.tag = 100
blueView.isUserInteractionEnabled = true
blueView.backgroundColor = .blue
blueView.addGestureRecognizer(gesture)
view.addSubview(blueView)
let grey = MyViews(frame: CGRect(origin: CGPoint(x: 38.0, y: 20.0 ), size: CGSize(width: 279, height: 203.0)))
grey.tag = 200
grey.backgroundColor = .gray
grey.isUserInteractionEnabled = true
grey.addGestureRecognizer(gesture)
blueView.addSubview(grey)
let white = MyViews(frame: CGRect(origin: CGPoint(x: 56.0 , y: 17.0 ), size: CGSize(width: 182.0, height: 92)))
white.tag = 300
white.isUserInteractionEnabled = true
white.addGestureRecognizer(gesture)
grey.addSubview(white)
let result = blueView.hitTest(CGPoint(x: 157.5, y: 149.0), with: nil)
print(result ?? "no result")
}
我正在模拟这条线上的触摸let result = blueView.hitTest(CGPoint(x: 157.5, y: 149.0), with: nil)
但是这个函数的响应:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
for subview in self.subviews.reversed() {
let subPoint = subview.convert(point, from:self);
if let result = subview.hitTest(subPoint, with:event) {
return result;
}
}
return nil
}
它总是为零。我不明白为什么它应该返回白色视图。
你们知道为什么这个函数没有返回正确的视图吗?
非常感谢你的帮助。
您的 hitTest 似乎从不检查该点是否在视图中。试一试:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// if there are subviews, step through them
// if the subview contains the point, call hitTest on the subview to see if the subview's subviews contain the point
// if they do, return the result,
// if they don't, return the subview that does contain the point.
for subview in self.subviews.reversed() {
let subPoint = subview.convert(point, from:self)
if subview.point(inside: subPoint, with: event) == true {
if let result = subview.hitTest(subPoint, with: event) {
return result
} else {
return subview
}
}
}
// none of the subviews contain the point,(or there are no subviews) does the current view contain the point?
// if yes, return self. otherwise, return nil
if self.point(inside: point, with: event) == true {
return self
} else {
return nil
}
}