如何识别我点击了哪个 UIImageview?

How recognize which UIImageview I've tapped?

我想实现一种可触摸编辑的矩阵。 一系列黑色或白色单元格,如果轻按它们,它们会从黑色变为黑色,反之亦然。 为此,我将使用在堆栈视图中排列的 UIImageView 和点击手势识别器。但是我怎么知道哪个 UIImageView 被点击了呢?我可以通过哪种方式更改 UIImageView 中的 UIImage?

如果它们只是白色和黑色,那么使用 UIView 并将其 backgroundColor 设置为 .white.black 会简单得多。您可以使用 UIViewtag 属性 来识别它们。

在您的 gestureRecognizer 处理程序中,recognizer.view 告诉您触发手势的 view

您可以在 Interface Builder 中分配标签。例如,如果您有一个 8x8 的正方形数组,您可以使用一个 2 位数字,其中第一个数字是行,第二个数字是列。因此,您的标签将是 1112、...、8788.

func squareTapped(recognizer: UIGestureRecognizer) {
    if let view = recognizer.view {
        let tag = view.tag
        let row = tag / 10
        let col = tag % 10
        print("The view at row \(row), column \(col) was tapped")

        if view.backgroundColor == .black {
            view.backgroundColor = .white
        } else {
            view.backgroundColor = .black
        }
    }
}

如果您确实想使用图像,请将图像加载为您的 viewController 的属性,并根据图像的行和列分配它们。在这里,我使用了 Outlet Collection 来保存所有 UIImageView。在 Interface Builder 中,您会将每个单元连接到 squares 属性.

class BoardViewController: UIViewController {
    let blackImage = UIImage(named: "blackImage")!
    let whiteImage = UIImage(named: "whiteImage")!
    @IBOutlet var squares: [UIImageView]!
    var recognizersAdded = false

    func setUpBoard() {
        for imageview in squares {
            if !recognizersAdded {
                let recognizer = UITapGestureRecognizer(target: self, action: #selector(squareTapped))
                imageview.addGestureRecognizer(recognizer)
                imageview.isUserInteractionEnabled = true
            }

            let tag = view.tag
            let row = tag / 10
            let col = tag % 10

            // Just for demo purposes, set up a checkerboard pattern
            if (row + col) % 2 == 0 {
                imageview.image = blackImage
            } else {
                imageview.image = whiteImage
            }
        }
        recognizersAdded = true
    }

    func squareTapped(recognizer: UIGestureRecognizer) {
        if let view = recognizer.view as? UIImageView {
            let tag = view.tag
            let row = tag / 10
            let col = tag % 10
            print("The view at row \(row), column \(col) was tapped")

            if view.image == blackImage {
                view.image = whiteImage
            } else {
                view.image = blackImage
            } 
        }
    }
}

为每个 UIImageView 分配一个标签并在其上添加点击手势。

在点击任何视图时,您可以获取被点击的图像视图:

UIImageView *imageView = gestureRecogniser.view

我现在用的代码是这样的,效果很好。 但我想使用平移手势 (UIPanGetureRecognizer) 来更改 UIView 的颜色。我该怎么办?

class ViewController: UIViewController {
@IBOutlet weak var PrincipalRowStack: UIStackView!

let rowsNumber=10
let colsNumber=10

override func viewDidLoad() {
    // Do any additional setup after loading the view, typically from a nib.


    super.viewDidLoad()

    var rowsStack = [UIStackView]()
    var images = [[UIView]]()
    var gestRec = [[UITapGestureRecognizer]]()
    for r in 0...rowsNumber-1 {
        rowsStack.append(UIStackView())
        rowsStack[r].axis = .horizontal
        rowsStack[r].distribution = .fillEqually
        images.append([UIView]())
        gestRec.append([UITapGestureRecognizer]())
        for c in 0...colsNumber-1{
            images[r].append(UIView())
            gestRec[r].append(UITapGestureRecognizer())
            gestRec[r][c].addTarget(self, action: #selector(ViewController.Tap(_:)))
            images[r][c].contentMode = .scaleToFill
            images[r][c].layer.borderWidth = 1
            images[r][c].layer.borderColor = UIColor(red:0.5, green:0.5, blue:0.5, alpha: 1.0).cgColor
            images[r][c].addGestureRecognizer(gestRec[r][c])
            rowsStack[r].addArrangedSubview(images[r][c])
        }
    }
    for s in rowsStack{
        PrincipalRowStack.addArrangedSubview(s)
    }

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}



func Tap(_ recognizer: UITapGestureRecognizer) {

    if let view = recognizer.view {
        //let tag = view.tag
        //let row = tag / 10
        //let col = tag % 10
        print("Tapped!")

        if view.backgroundColor == .black {
            view.backgroundColor = .white
        } else {
            view.backgroundColor = .black
        }
    }

}
}

我解决了将 PanGestureRecognizer 添加到 principalStackView 的问题,然后我将此函数与 hitTest 结合使用以了解哪个视图应更改颜色。

func pan(_ recognizer: UIPanGestureRecognizer){
    if (recognizer.state == .began ||
        recognizer.state == .changed)
    {
        let loc = recognizer.location(in: principalRowStack)
        let view = principalRowStack.hitTest(loc, with: UIEvent())
        view?.backgroundColor = .black


    }

}