如图所示很简单的一个功能
有一个UITableView,TableViewCell里面包含一个下拉框控件,控件用的是我之前写的一个类似Web端dropdownlist的功能。但是实际使用起来的时候遇到一个问题,就是控件的点击区域不包含在当前UIView里面。
比如图中这样,当点击下拉选项的时候触发的是UITableView的事件,不会触发到下拉框的选择事件,原因很简单,事件的先后顺序而已。
这里使用到的解决方法也蛮简单的。
hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView?
iOS系统检测到手指触摸(Touch)操作时会将其放入当前活动Application的事件队列,UIApplication会从事件队列中取出触摸事件并传递给key window(当前接收用户事件的窗口)处理,window对象首先会使用hitTest:withEvent:方法寻找此次Touch操作初始点所在的视图(View),即需要将触摸事件传递给其处理的视图,称之为hit-test view。
window对象会在首先在view hierarchy的顶级view上调用hitTest:withEvent:,此方法会在视图层级结构中的每个视图上调用pointInside:withEvent:,如果pointInside:withEvent:返回YES,则继续逐级调用,直到找到touch操作发生的位置,这个视图也就是hit-test view。
在我的项目中,我是把hitTest部分写在UITableViewCell里面如下:
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
if tableView?.numberOfRowsInSection(0) > 0 {
for i in 0..<tableView!.numberOfRowsInSection(0) {
if let cell = tableView?.cellForRowAtIndexPath(NSIndexPath(forRow: i, inSection: 0)) as? Cell {
if cell.tag != -99 {
if let agTableView = cell.textFieldName.agTableView {
if agTableView.alpha == 1 {
let pFrame = agTableView.converRect(agTableView.bounds, toView: tableView!)
let agFrame = CGRectMake(pFrame.orign.x, pFrame.orign.y - self.frame.orign.y, pFrame.width, pFrame.height)
if CGRectContainsPoint(agFrame, point) {
return agTableView
}
}
}
}
}
}
}
return super.hitTest(point, withEvent: event)
}
代码部分很简单,就不解释了。
总结:当控件超出了UIView的范围,或者被其它控件挡住了的时候,都可以用类似的方法解决,只要知道事件触发的先后顺序就行了。
原文链接:iOS的UIButton被挡住或者超出所在UIView的范围怎么办,转载请注明来源!