From an architectural perspective, the answer is "you don't."
The correct answer is to have a Model class, probably with properties that represent different parts of the model. When the user taps the button, it affects the model in some way (the button action should call a method on a model object. The method's name would be something that would make sense to the user of the app.)
When the model changes state, it should notify any Observers. Look up the Observer pattern, but basically, it's like an array of delegates.
The cell with the UIImage should be set up to observe the model and react to changes in the model which in this case happened to be due to the button tap, but could have occurred through other means as well.
First you need a model class:
class MyModel {
typealias Observer = (MyModel) -> Void
func add(observer: @escaping Observer) {
observers.append(observer)
}
func updateImage() {
// do what you need to do to update `myImage`
// then call:
update()
}
private (set) var image: UIImage?
private var observers = [Observer]()
private func update() {
for each in observers {
each(self)
}
}
}
Then make an instance of this model in your view controller:
let model = MyModel()
Now pass your view controller's model to each of the cells inside the cellForItemAt
method.
cell.model = model
In the cell that has the image, you give it a model property like this:
var model: MyModel! {
didSet {
model.add(observer: { [weak self] updated in
self?.imageView.image = updated.image
})
}
}
The cell that has the button would have a normal model property and in the IBAction for the button, you would call model.updateImage()
.
var model: MyModel!
@IBAction func buttonTapped(_ sender: Any) {
model.updateImage()
}