子视图上的hitTest在UIGestureRecognizerState.Began中返回nil

时间:2014-11-17 11:16:45

标签: ios swift uigesturerecognizer

我有一个tableView(嵌入在导航控制器中),附有一个longPress手势识别器。当用户在tableview上按下一段时间时,会出现一个名为coverView的(模态)子视图。 CoverView有多个名为'characterView'的子视图。只要长按手势正在进行,用户就可以选择一个characterView。一旦用户抬起手指,CoverView将被移除。

问题:在用户移动手指之前,我需要知道在显示coverView时会立即点击哪个characterView。这是我的相关代码:

    func showCoverView (longpressgesture: UILongPressGestureRecognizer){

    var point = longpressgesture.locationInView(coverView) 

    switch (longpressgesture.state){

    case UIGestureRecognizerState.Began:

        //coverView is added     
        navigationController?.view.addSubview(coverView)

        var hitTestView = coverView.hitTest(point, withEvent: nil)

        println("hittestview is \(hitTestView)")// returns NIL in most cases. Why?

    case UIGestureRecognizerState.Changed:

        var hitTestView = coverView.hitTest(point, withEvent: nil) 

        println("hittestview is \(hitTestView)")// returns a characterView. No problem here.

    default:
        break
    }

}

问题是hitTest:withEvent在大多数情况下返回nil(有时它会随机返回正确的视图),只要触摸还没有移动。一旦用户开始拖动,状态就会发生“已更改”更改,并且不会出现问题。

有人知道这种行为的原因吗?

1 个答案:

答案 0 :(得分:0)

好的,是时候回答我自己的问题了。首先:我使用了'点'在将coverView添加为子视图之前分配的变量。当我记录CGPoint时,我发现该点以像素而不是点表示。当参数是实际添加到屏幕的视图时,locationInView方法显然只返回一个有效点。

当我解决这个问题时,hitTest返回了coverView本身,但没有返回其中一个子视图(characterView)。

所以,第二部分是在执行hitTest之前在coverView上调用layoutIfNeeded。这解决了我的问题,hitTest现在返回正确的视图。显然背景中有一些东西阻止了子视图'在新子视图上执行hitTest时要注意的子视图。

新代码:

    func showCoverView (longpressgesture: UILongPressGestureRecognizer){

var point = longpressgesture.locationInView(coverView) 

switch (longpressgesture.state){

case UIGestureRecognizerState.Began:

    //coverView is added     
    navigationController?.view.addSubview(coverView)

    var firstPoint = longpressgesture.locationInView(coverView) //solution part A

    coverView.layoutIfNeeded() //solution part B

    var hitTestView = coverView.hitTest(firstPoint, withEvent: nil)

    println("hittestview is \(hitTestView)")// returns a characterView. Problem solved.

case UIGestureRecognizerState.Changed:

    var hitTestView = coverView.hitTest(point, withEvent: nil) 

    println("hittestview is \(hitTestView)")// returns a characterView. No problem here.

default:
    break
}

}