I won't get to into the weeds on what my app is ultimately doing but the issue I'm having is when I click on one of 6 button that all have a UIImage in their imageView I then try to reference the image name (the images are coming from my assets) to switch over which button was pressed and use the results to update a label.
The values are being set and printing out in the action, however the switch statement always falls through to default and I can't figure out why. Are the button imageViews effecting the image names?
@IBOutlet var feelingLabel: UILabel!
var feelingImage: UIImage? {
didSet {
switch feelingImage {
case UIImage(named: "happyFace"):
self.feelingLabel.text = "feeling happy"
case UIImage(named: "fineFace"):
self.feelingLabel.text = "feeling fine"
case UIImage(named: "angryFace"):
self.feelingLabel.text = "feeling angry"
case UIImage(named: "anxiousFace"):
self.feelingLabel.text = "feeling anxious"
case UIImage(named: "sadFace"):
self.feelingLabel.text = "feeling sad"
case UIImage(named: "sickFace"):
self.feelingLabel.text = "feeling sick"
default:
self.feelingLabel.text = "feeling..."
}
}
}
// all six buttons are connected to this action
@IBAction func feelingButtonTapped(_ sender: UIButton) {
guard let selectedFeelingImage = sender.imageView?.image,
selectedFeelingImage != self.feelingImage else {
self.feelingImage = nil
return
}
self.feelingImage = selectedFeelingImage
print(selectedFeelingImage)
print(self.feelingImage)
}
A UIImage
does not have a "name" ... your image resource does, and that's what you are using to load the image. However, once it is loaded, there is no association with the resource name.
While comparing the .pngData
may work, it would be a very inefficient approach.
One very good approach would be to track your buttons in an array, and use the array index to determine which button was tapped.
Another approach would be to subclass UIButton
and add your own .imageName
property.
For example:
class NamedButton: UIButton {
var imageName: String = ""
}
Now, in code, your button creating becomes:
if let img = UIImage(named: "happyFace") {
let btn = NamedButton()
btn.setImage(img, for: [])
btn.imageName = "happyFace"
btn.addTarget(self, action: #selector(feelingButtonTapped(_:)), for: .touchUpInside)
}
your "current selection" can be:
var feelingImageName: String = "" {
didSet {
switch feelingImageName {
case "happyFace":
self.feelingLabel.text = "feeling happy"
case "fineFace":
self.feelingLabel.text = "feeling fine"
case "angryFace":
self.feelingLabel.text = "feeling angry"
case "anxiousFace":
self.feelingLabel.text = "feeling anxious"
case "sadFace":
self.feelingLabel.text = "feeling sad"
case "sickFace":
self.feelingLabel.text = "feeling sick"
default:
self.feelingLabel.text = "feeling..."
}
}
}
and your button action can be:
@IBAction func feelingButtonTapped(_ sender: UIButton) {
guard let btn = sender as? NamedButton,
btn.imageName != self.feelingImageName else {
self.feelingImageName = ""
return
}
self.feelingImageName = btn.imageName
print(btn.imageName)
print(self.feelingImageName)
}
If you are using Storyboard / Interface Builder for your layout, you can make the .imageName
property @IBInspectable
so you can set it at design-time:
class NamedButton: UIButton {
@IBInspectable var imageName: String = ""
}