如何在其父视图范围之外启用视图的触摸?
Posted
技术标签:
【中文标题】如何在其父视图范围之外启用视图的触摸?【英文标题】:How to enable touches of a view outside bounds of its superview? 【发布时间】:2018-06-12 12:40:39 【问题描述】:我有一个将clipToBounds
设置为false 的容器和一个超出其边界的视图。越界视图无法识别触摸事件。
【问题讨论】:
【参考方案1】:只需将此类添加到您的视图中
class MyView: UIView
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool
for subview in subviews as [UIView]
if !subview.isHidden
&& subview.alpha > 0
&& subview.isUserInteractionEnabled
&& subview.point(inside: convert(point, to: subview), with: event)
return true
return false
【讨论】:
谢谢,但我正在寻找不涉及子类化的解决方案,因为我有一个可重用的视图,该视图将具有超出范围的组件。对每个视图控制器的每个视图进行子类化是一种错误的方法,我想在其中添加包含越界组件的视图。【参考方案2】:这是一个扩展,使您能够允许触摸容器中的剪辑子视图。将此文件粘贴到您的项目中并设置containerView.allowTouchesOfViewsOutsideBounds = true
public extension UIView
private struct ExtendedTouchAssociatedKey
static var outsideOfBounds = "viewExtensionAllowTouchesOutsideOfBounds"
/// This propery is set on the parent of the view that first clips the content you want to be touchable
/// outside of the bounds
var allowTouchesOfViewsOutsideBounds:Bool
get
return objc_getAssociatedObject(self, &ExtendedTouchAssociatedKey.outsideOfBounds) as? Bool ?? false
set
UIView.swizzlePointInsideIfNeeded()
subviews.forEach($0.allowTouchesOfViewsOutsideBounds = newValue)
objc_setAssociatedObject(self, &ExtendedTouchAssociatedKey.outsideOfBounds, newValue, .OBJC_ASSOCIATION_RETAIN)
func hasSubview(at point:CGPoint) -> Bool
if subviews.count == 0
return self.bounds.contains(point)
return subviews.contains(where: (subview) -> Bool in
let converted = self.convert(point, to: subview)
return subview.hasSubview(at: converted)
)
static private var swizzledMethods:Bool = false
@objc func _point(inside point: CGPoint, with event: UIEvent?) -> Bool
if allowTouchesOfViewsOutsideBounds
return _point(inside:point,with:event) || hasSubview(at: point)
return _point(inside:point,with:event)
static private func swizzlePointInsideIfNeeded()
if swizzledMethods
return
swizzledMethods = true
let aClass: AnyClass! = UIView.self
let originalSelector = #selector(point(inside:with:))
let swizzledSelector = #selector(_point(inside:with:))
swizzle(forClass: aClass, originalSelector: originalSelector, swizzledSelector: swizzledSelector)
【讨论】:
swizzle(forClass: aClass, originalSelector: originalSelector, swizzledSelector: swizzledSelector) 这行不行。 不编译。什么是“调酒”?以上是关于如何在其父视图范围之外启用视图的触摸?的主要内容,如果未能解决你的问题,请参考以下文章
如何检测拖动到那里的子视图中的触摸(或获取哪个子视图位于其父视图中的点击下方的最快方法)