User interface 视图中的Swift-UIPanRecognitor

User interface 视图中的Swift-UIPanRecognitor,user-interface,layout,uigesturerecognizer,uipangesturerecognizer,uistackview,User Interface,Layout,Uigesturerecognizer,Uipangesturerecognizer,Uistackview,我想在UIStack视图中创建UIPanRecognitor 有一个大正方形,它是一个StackView,包含9个标签。 我的目标是,当我开始在StackView中拖动手指时,如果标签包含该接触点,则其颜色应为蓝色,并持续不断。如果我抬起手指,所有标签的背景色都会变回白色。 标签位于OutletCollection中。 这是我的密码: @IBOutlet var testLabels: [UILabel]! @IBAction func handlePan(recognizer:UIPanGes

我想在UIStack视图中创建UIPanRecognitor

有一个大正方形,它是一个StackView,包含9个标签。 我的目标是,当我开始在StackView中拖动手指时,如果标签包含该接触点,则其颜色应为蓝色,并持续不断。如果我抬起手指,所有标签的背景色都会变回白色。
标签位于OutletCollection中。
这是我的密码:

@IBOutlet var testLabels: [UILabel]!
@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    var touchedPoint: CGPoint!
    if let view = recognizer.view{
        if recognizer.state == .began || recognizer.state == .changed {
            touchedPoint = recognizer.location(in: view)
            for index in testLabels.indices {

                if testLabels[index].frame.contains(touchedPoint) {

                    testLabels[index].backgroundColor = UIColor.blue

                }
            }
        }
        if recognizer.state == .ended {
            for index in testLabels.indices {

                testLabels[index].backgroundColor = UIColor.white

            }
        }
    }
现在,例如,当我触摸左上角的正方形并开始向右拖动手指时,整个第一列会变成蓝色,然后第二列变成蓝色,然后第三列变成蓝色。当我触摸第一行的任何标签时会发生这种情况,但当我触摸其他方块时不会发生任何情况。
第一次,我试图通过像处理OutletCollection一样处理正方形来解决我的问题(没有StackView),识别器工作得很好!我之所以尝试使用StackView,是因为它更容易进行布局(只需要一些约束,没有StackView,这是一场噩梦)。
我非常感谢你的帮助。谢谢。
编辑:这个可能有用吗?


每个标签都是其包含的堆栈视图(也可能是堆栈视图的子视图)的子视图,每个标签都有自己的坐标空间

假设您的
ui感知识别器
已分配给视图控制器的视图,则需要转换坐标/帧

这应该适合您:

@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    var touchedPoint: CGPoint!

    if let view = recognizer.view{

        if recognizer.state == .began || recognizer.state == .changed {

            touchedPoint = recognizer.location(in: view)

            for index in testLabels.indices {

                // translate / convert the label's bounds from its frame to the view's coordinate space
                let testFrame = view.convert(testLabels[index].bounds, from:testLabels[index] )

                // check the resulting testFrame for the point                  
                if testFrame.contains(touchedPoint) {

                    testLabels[index].backgroundColor = UIColor.blue

                }
            }
        }
        else if recognizer.state == .ended {
            for index in testLabels.indices {

                testLabels[index].backgroundColor = UIColor.white

            }
        }
    }
}
您还可以使用集合中对象的
而不是索引来简化代码。这在功能上与上述相同,但可能更简单一些:

@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    var touchedPoint: CGPoint!

    if let view = recognizer.view{

        if recognizer.state == .began || recognizer.state == .changed {

            touchedPoint = recognizer.location(in: view)

            for lbl in testLabels {

                // translate / convert the label's bounds from its frame to the view's coordinate space
                let testFrame = view.convert(lbl.bounds, from:lbl )

                // check the resulting testFrame for the point
                if testFrame.contains(touchedPoint) {

                    lbl.backgroundColor = .blue

                }
            }
        }
        else if recognizer.state == .ended {
            for lbl in testLabels {

                lbl.backgroundColor = .white

            }
        }
    }
}