Search code examples
iosiphoneswiftuiimageviewuitapgesturerecognizer

How recognize which UIImageview I've tapped?


I want to realize a sort of matrix editable by touch. A series of black or white cell that if tapped switch form black to withe or viceversa. For doing this i will use UIImageView arranged in stack view a Tap Gesture Recognizer. But how do I know which UIImageView was tapped? And in which way I can change the UIImage in the UIImageView?


Solution

  • If they are just white and black, it would be much simpler to use a UIView and set its backgroundColor to .white or .black. You can use the tag property of the UIViews to identify them.

    In your gestureRecognizer handler, the recognizer.view tells you the view that triggered the gesture.

    You can assign the tags in Interface Builder. For example, if you have an 8x8 array of squares, you could use a 2-digit number where the first digit is the row and the second digit is the column. Thus, your tags would be 11, 12, ..., 87, 88.

    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
            }
        }
    }
    

    If you do want to use images, then load the images as properties of your viewController and assign them based upon the row and column of your image. Here I have used an Outlet Collection to hold all of the UIImageViews. In Interface Builder, you'd connect each of your cells to the squares property.

    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
                } 
            }
        }
    }