hitTest方法,简而言之,就是给定一个点,返回一个view或layer,判定当前是哪一个view或layer被点中了
<!--more-->
原理
当用户触摸屏幕的时候,系统会依次调用view层次中各个子view的hitTest方法,来判断当前是哪个view被点中,决定谁是first responder。关于这点,这篇文章总结得不错:iOS事件分发机制(一) hit-Testing
默认的实现就是触摸点是否在此view的范围内,开发者可以重写此方法,来实现不同的逻辑。具体来说有2种常见的场景
重写UIView的hitTest方法
比如为了扩大某个view的点击区域,就可以用这个方法
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
let (x, y) = (bounds.maxX - point.x, bounds.maxY - point.y)
let r = x * x + y * y
let lo = sliderRadius - sliderWidth - hitAreaOffset
let hi = sliderRadius + sliderWidth + hitAreaOffset
if (r >= lo * lo && r <= hi * hi) {
return super.hitTest(point, withEvent: event)
}
return nil
}
如上,通常来说view的hitTest方法不需要手动调用,而是iOS系统在需要的时候调用
重写CALayer的hitTest方法
有时自定义的view包含多个layer,所以当此view被点中的时候,还希望知道具体是哪个layer区域被点中,从而进行不同的处理。这时候可以通过重写layer的hitTest方法进行判断
override func hitTest(p: CGPoint) -> CALayer? {
let (dx, dy) = (p.x - position.x, p.y - position.y)
let r = radius + markerBorderWidth + hitAreaOffset
return (dx * dx + dy * dy <= r * r) ? self : nil
}
与view的hitTest不同的是,layer的hitTest方法通常需要开发者自己调用。比如在自定义的view上绑定了一个UITapGestureRecognizer,并且设置了delegate,那么当tap事件触发之后,就会进入以下方法
override func gestureRecognizerShouldBegin(gr: UIGestureRecognizer) -> Bool
需要注意,如果view上绑定了多个recognizer,那么每个手势都会触发进入此方法一次。在此方法中,可以手动调用layer的hitTest方法,来判断是哪个layer被点中
override func gestureRecognizerShouldBegin(gr: UIGestureRecognizer) -> Bool {
let pos = gr.locationInView(self)
if let group = selectedMarker as? WheelMarkerGroup where group.expanded {
let p = layer.convertPoint(pos, toLayer: group.expandLayer)
for marker in group.zones {
if (marker.hitTest(p) != nil) {
activeMarker = marker
return true
}
}
}
return false
}
<script type="text/javascript">
$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('<ul/>').addClass('pre-numbering').hide();
$(this).addClass('has-numbering').parent().append($numbering);
for (i = 1; i <= lines; i++) {
$numbering.append($('<li/>').text(i));
};
$numbering.fadeIn(1700);
});
});
</script>
分享到:
相关推荐
DevExpress HitTest的运用
as3 hitTest实例,有需要的下去看看,我也挣点分
更改UIView对响应的交互方式。解决获取被遮挡住视图的响应事件。主要重新写父类的hitTest:withEvent:和pointInside:withEvent:方法实现。
精彩编程与编程技巧-HitTest的妙用 ...
ios的hitTest方法以及不规则区域内触摸事件处理方法 明白点就是圆的触发点
iOS开发-事件传递与响应者链中的hitTest方法和pointInside方法
国外大师写的As3.0 碰撞检测文件,静态的,附有使用方法。效率非常高,需要的下。
2个例子来自http://www.andybeaulieu.com/Home/tabid/67/EntryID/160/Default.aspx http://blogs.microsoft.co.il/blogs/alex_golesh/archive/2009/08/11/silverlight-quick-tip-how-to-perform-a-hit-test.aspx这里...
iOS点击响应 hitTest & pointInside,实现 hitTest & pointInside
Android下面的命中测试。 1,创建一个矩形。 2,旋转这个矩形。 3,点击矩形旋转后所在的区域。 这个程序能够判断出你所点击的点,在不在该矩形旋转后所包含的区域之内。这就是所谓的“命中测试(HitTest)”
hitTest:withEvet 调用过程 比如如果是当前的View A, 还有一个viewB 如果不重写 hitTest 方法,那么 系统默认是先调用viewA的hitest 方法,然后再调用viewB的htest方法。 系统的调用过程,跟下面的重写hitest的...
命中测试 使用hitTest实现重叠点击时响应下方视图
如果不是规则元件与元件之间的碰撞可使用:位图像素碰撞BitmapData.hitTest()这个是高精度像素碰撞不过效率要差一点点或者使用,我上传的文件,HitTest.complexHitTestObject(mc,mc1)这种方式是行的。HitTest是经过...
带有碰撞检测游戏示例的透明PNG上JavaScript hitTest
制作时间:2010年3月20日15:40:09 ...的碰撞命令hitTest和对鼠标按钮的判断控制。 是一个不错的学习实例。 压缩包中包括源代码、截图、制作步骤文档、以及flash播放器 希望发布上来能对朋友们有所帮助。
....这是一个关于 WPF HitTestCore方法的实用例子,源码是从WPF的源码里面反编译出来的,我使了大力气把重点内容剥离出来,做了这个例子.而且我现在的项目也在广泛应用。 主要功能是使一个很细的显示对象,十分方便...
ios事件响应链,重写- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event以及- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event方法来查看系统响应事件的逻辑
flutter_touch_hittest_demo 尝试在以下位置组合Letitbe的代码: 目前尚未完成