`

hitTest

 
阅读更多

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>
分享到:
评论

相关推荐

    Hittest As3.0碰撞检测

    在ActionScript 3.0(AS3.0)中,Hittest是用于实现对象间碰撞检测的核心技术。这篇由国外大师编写的关于“Hittest As3.0碰撞检测”的资源,提供了一种静态且高效的解决方案,适用于那些需要在游戏中或者交互式应用...

    精彩编程与编程技巧-HitTest的妙用...

    ### 精彩编程与编程技巧-HitTest的妙用 #### 一、HitTest功能简介 在开发图形用户界面(GUI)应用时,我们经常需要处理用户输入,特别是鼠标事件,比如点击、移动等。其中`HitTest`方法是一个非常实用的功能,它...

    swift-iOS开发-事件传递与响应者链中的hitTest方法和pointInside方法

    本篇文章将深入探讨在事件传递与响应者链中,hitTest方法和pointInside方法的重要作用。 首先,我们要了解什么是事件响应者链。在iOS中,事件响应者链是由一系列响应者对象构成的,它们按照特定顺序接收并处理用户...

    hitTest 与pointInside 方法的应用

    在这个过程中,`hitTest:withEvent:` 和 `pointInside:withEvent:` 方法扮演着关键角色。本文将深入探讨这两个方法的使用及其在自定义视图交互中的应用。 首先,让我们了解响应者链的概念。响应者链是由一系列响应...

    ios的hitTest方法以及不规则区域内触摸事件处理方法

    本文将深入探讨`hitTest`方法及其在处理不规则区域内触摸事件中的应用,特别是在圆等非矩形形状的控件中的实现。 `hitTest`方法是UIView类的一个重要方法,它用于确定视图层次结构中哪个视图应该接收触摸事件。默认...

    flash 碰撞检测hittest

    `hitTest`方法在ActionScript 3(AS3)中扮演着至关重要的角色,用于检测两个显示对象是否在视觉上重叠。本篇文章将深入探讨`hitTest`方法的使用、原理及其在实际项目中的应用。 一、`hitTest`方法概述 `hitTest`...

    iOS点击响应 hitTest & pointInside

    `hitTest:withEvent:` 和 `pointInside:withEvent:` 是Objective-C中UIResponder类(包括UIView和UIViewController)的两个关键方法,它们在处理触摸事件时起着决定性作用。这两个方法涉及到视图层次结构中的触摸...

    Delphi DevExpress HitTest的运用

    DevExpress HitTest的运用

    Silverlight3 HitTest 的2个比较好的例子

    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这里...

    HitTest:使用hitTest实现重叠点击时响应下方视图

    `hitTest`是UIKit框架中的一个方法,用于确定用户触摸屏幕时,应该响应触摸事件的视图。这个方法在处理用户交互和事件传递时扮演着关键角色。本篇将深入探讨如何使用Swift中的`hitTest`来实现在视图重叠时,点击事件...

    Hittest.js (PNG Collision Detection):带有碰撞游戏示例的透明PNG上的Javascript HitTest-开源

    "Hittest.js"是一个专门为透明PNG图像提供碰撞检测功能的JavaScript库,它允许开发者在网页游戏中实现精确的物体碰撞效果。这个库是开源的,意味着它的源代码对公众开放,开发者可以自由地查看、学习和修改,以适应...

    Android下面的命中测试(HitTest)

    Android下面的命中测试。 1,创建一个矩形。 2,旋转这个矩形。 3,点击矩形旋转后所在的区域。 这个程序能够判断出你所点击的点,在不在该矩形旋转后所包含的区域之内。这就是所谓的“命中测试(HitTest)”

    举例讲解iOS应用开发中hitTest触摸事件的编写方法

    `hitTest:withEvent:` 是一个重要的方法,用于确定哪个视图应该响应特定的触摸事件。这个方法在用户触摸屏幕时被系统自动调用,用于遍历视图层次结构,找到最合适的视图来处理触摸事件。 `hitTest:withEvent:` 的...

    cxGrid弹出菜单和TcxCustomGridHitTest

    它提供了诸如`HitTest`这样的方法,该方法可以返回一个`TcxGridHitTestInfo`结构,其中包含了关于鼠标点击位置的信息,如是否在行头、列头、数据区或者边框上。你可以利用这些信息来判断是否应该显示弹出菜单,以及...

    不规则碰撞

    如果不是规则元件与元件之间的碰撞可使用:位图像素碰撞BitmapData.hitTest()这个是高精度像素碰撞不过效率要差一点点或者使用,我上传的文件,HitTest.complexHitTestObject(mc,mc1)这种方式是行的。HitTest是经过...

    demoHitTest

    然而,通过自定义hitTest方法,开发者可以改变这种行为,使子视图的全区域都变得可交互。 首先,我们来理解一下“响应链”(Responder Chain)的概念。在iOS中,响应链是事件处理的一个机制,它由一系列可以响应并...

    DevExpress之ChartControl实现饼状图百分比演示实例

    - ChartControl支持用户交互,例如悬停提示、点击选择等,可以设置`HitTest`和`Trackball`选项来增强用户体验。 通过以上步骤,我们可以创建一个显示百分比的饼状图,有效地展示了各部分在整体中的比例。这在数据...

    iOS 为移动动画中的View添加touch事件

    UIView通过 `-hitTest:withEvent:` 方法确定哪个子视图应该接收这个触控事件。在进行动画操作时,如果我们的视图正在执行动画,可能会因为坐标系统的改变而影响到正常的手势识别。 为了在动画过程中正确处理touch...

Global site tag (gtag.js) - Google Analytics