如何在我的触摸位置获得所有UIViews?
在下图中,我需要用黄线接触所有UIViews。
来自UI层次结构的代码段
我在寻找与SpriteKit类似的功能,我们用它来获取所有节点
self.nodes(at: touch.location(in: self))
答案 0 :(得分:3)
您必须遍历层次结构中的所有视图,如:
extension UIView {
func allViews(for touch: UITouch) -> [UIView] {
return self.allViews(at: touch.location(in: self))
}
func allViews(at point: CGPoint) -> [UIView] {
var stack = [UIView]()
var result = [UIView]()
stack.append(self)
while let view = stack.popLast() {
let localPoint = view.convert(point, from: self)
if view.bounds.contains(localPoint) {
result.append(view)
}
stack.append(contentsOf: view.subviews)
}
return result
}
}
您可以从任何包含所有适当视图的超级视图(例如视图控制器的视图)或窗口开始。第二种方法的要点必须相对于由self
表示的视图边界。
答案 1 :(得分:0)
在UIKit中,响应者链的工作方式与this类似,我认为没有办法获取所有列表,因为触摸“触发”直到响应者捕获它而不是进一步。
答案 2 :(得分:0)
func subviewsThatContain(point: CGPoint, in view: UIView) -> [UIView] {
var views = [UIView]()
for subview in view.subviews {
if subview.frame.contains(subview.convert(point, from: self.view)) {
views.append(subview)
}
views += subviewsThatContain(point: point, in: subview)
}
return views
}
和函数调用看起来像这样
var allViews = [self.view] + subviewsThatContain(in: self.view, point: touch.location(in: self.view))
答案 3 :(得分:0)
这可以通过两个步骤实现:
从某个视图开始获取所有视图
func descendants(of view: UIView) -> [UIView] {
return view.subviews + view.subviews.flatMap(descendants(of:))
}
过滤包含触摸点的视图:
let touchLocation = touchGesture.location(in: nil)
let matchingViews = descendants(of: UIApplication.shared.keyWindow!)
.filter { $0.convert($0.bounds, to: nil).contains(touchLocation) }
答案 4 :(得分:-2)
您可以使用hittest检查所有视图层次结构
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let point = targetPoint,
var view = super.hitTest(point, with: event) else {
return
}
var views: [UIView] = [view]
while view != nil {
view = view.hitTest(point, with: event)
if view != nil {
views.append(view!)
}
}
}