mikro098
mikro098

Reputation: 2353

Distinguish which button was clicked in custom UIView

I have a custom class which inherits from UIView inside of which is a UIImageView and button. I'm adding them to my storyboard as UIView and let's say there are two views. I have a delegate and a function which executes when the button is pressed and it works for both UIViews.

My problem is that I don't know how to tell which one was clicked. I need to pass it to another VC and then display suitable image in the UIView which was clicked. I've been thinking of setting ids or something but it does not seem like a very scalable idea. And I cannot simply add @IBAction because the view is UIView as a whole.

Inside the ViewController I've added them as @IBOutlets:

@IBOutlet weak var view: CustomImageView!
@IBOutlet weak var view2: CustomImageView!

EDIT: I'm pretty close to creating reusable and scalable solution - I'm just assigning the tag to every object and than passing it and retrieving it. Problem I've encountered is that I would like to access properties of a tag. I didn't find any solution on how to do it.

Upvotes: 1

Views: 181

Answers (1)

messeb
messeb

Reputation: 377

Solution with delegates You could add a custom delegate protocol for your custom view

protocol CustomViewDelegate {
    func didSelectCustomView(_ view: CustomView)
}

class CustomView: UIView {
    @IBOutlet weak var myImageView: UIImageView!
    @IBOutlet weak var myButton: UIButton!  

    weak var delegate: CustomViewDelegate?

    @IBAction func buttonPressed(sender: UIButton) {
        delegate?.didSelectCustomView(self)
    }
}

And in your ViewController you have to check from which view to delegate call comes:

class ViewController: UIViewController {
    @IBOutlet weak var view1: CustomView!
    @IBOutlet weak var view2: CustomView!

    override func viewDidLoad() {
        super.viewDidLoad()

        view1.delegate = self;
        view2.delegate = self;
    }
}

extension ViewController: CustomViewDelegate {
    func didSelectCustomView(_ view: CustomView) {
        if view == view1 {
            // view1 clicked
        } else {
            // view2 clicked
        }
    }
}

Solution with blocks Instead of a delegate, you could add an optional block that is executed if the button in the view was clicked:

class CustomView: UIView {
    @IBOutlet weak var myImageView: UIImageView!
    @IBOutlet weak var myButton: UIButton!

    var clicked: ((CustomView) -> Void)?

    @IBAction func buttonPressed(sender: UIButton) {
        clicked?(self)
    }
}

And in your ViewController, you can add the block to your views:

class ViewController: UIViewController {
    @IBOutlet weak var view1: CustomView!
    @IBOutlet weak var view2: CustomView!

    override func viewDidLoad() {
        super.viewDidLoad()

        view1.clicked = { view in

        }

        view2.clicked = { view in

        }
    }
}

Upvotes: 3

Related Questions