UIImage is equal to
You can convert your UIImage
instances to NSData
instances and compare them.
if let emptyImage = UIImage(named: "empty") {
let emptyData = UIImagePNGRepresentation(emptyImage)
let compareImageData = UIImagePNGRepresentation(image1.image)
if let empty = emptyData, compareTo = compareImageData {
if empty.isEqualToData(compareTo) {
// Empty image is the same as image1.image
} else {
// Empty image is not equal to image1.image
}
} else {
// Creating NSData from Images failed
}
}
How to compare two UIImage objects
One way is to convert them to image data first, and then compare that.
- (BOOL)image:(UIImage *)image1 isEqualTo:(UIImage *)image2
{
NSData *data1 = UIImagePNGRepresentation(image1);
NSData *data2 = UIImagePNGRepresentation(image2);
return [data1 isEqual:data2];
}
Apply a comparable value type Int to an UIImage object in Swift 4
Use a struct and add a custom equality operator
struct Item : Equatable {
let image : UIImage
let value : Int
static func ==(lhs: Item, rhs: Item) -> Bool {
return lhs.value == rhs.value
}
}
Then create instances of Item
assigning the images and the appropriate values
let item1 = Item(image : UIImage(named: "PigAnimal")!, value: 1)
let item2 = Item(image : UIImage(named: "PigWord")!, value: 1)
and compare
if gameMode == 1 {
if item1 == item2 {
scoreInt += 1
} else {
scoreInt -= 1
}
scoreLabel.text = "Score: \(scoreInt)"
}
Image set in storyboard is not equal with UIImage(named: sunrise ) object declared in code
You are correct. The equality operator that compares two different image instances (one set in storyboard and one instantiated in code) will not see them as being equal.
If you want the code to work as intended, either (1) set the image explicitly in viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = UIImage(named: "sunrise")
}
... or (2) compare them by getting their data representations, which should be equal, even if one was set in storyboard:
if (self.imageView.image?.pngData() == UIImage(named: "sunrise")?.pngData()) { // your code}
I must advise against using the 1st method however, since apparently the official docs (https://developer.apple.com/documentation/uikit/uiimage) advise against using == to compare UIImages directly. The recommended method to compare UIImages is with isEqual(_:). I tried this as well but the UIImage set in storyboard is still not found to be equal to the one set in code.
With the original code, I did a little further testing by printing out to the console the output of:
print(self.imageView.image)
on every button tap. The results:
image exist
Optional(<UIImage:0x600000898510 anonymous {3220, 3155}>)
sunrise
image exist
Optional(<UIImage:0x6000008b0fc0 named(sunrise) {3220, 3155}>)
sunset
image exist
Optional(<UIImage:0x600000898fc0 named(sunset) {500, 500}>)
sunrise
image exist
Optional(<UIImage:0x6000008b9830 named(sunrise) {3220, 3155}>)
sunset
image exist
Optional(<UIImage:0x6000008b4f30 named(sunset) {500, 500}>)
sunrise
image exist
Optional(<UIImage:0x600000898fc0 named(sunrise) {3220, 3155}>)
sunset
image exist
Optional(<UIImage:0x6000008bc900 named(sunset) {500, 500}>)
sunrise
Notice that only the first time does it show a UIImage with part of the string description 'anonymous'. All suceeding calls to the method just alternately print either "named(sunrise)" or "named(sunset)". And also notice that the hex values are always changing, indicating that each time UIImage() is called it initializes a new and different instance.
You can check this by setting the 2 UIImages to constant properties in the VC and testing again:
let sunriseImage = UIImage(named: "sunrise")
let sunsetImage = UIImage(named: "sunset")
In this case, substituting the constants wherever you use UIImage(named..) will result in unchanging hex values for each of the 2 UIImages, when printing to the console.
Here's the full code I'm using with the pngData() method (recommended):
import UIKit
// MARK: - ViewController: UIViewController
class ViewController: UIViewController {
let sunriseImage = UIImage(named: "sunrise")
let sunsetImage = UIImage(named: "sunset")
override func viewDidLoad() {
super.viewDidLoad()
}
@IBOutlet weak var imageView: UIImageView!
// MARK: Actions
@IBAction func sunRiseAndSet(sender: AnyObject) {
// Fade out
imageView.fadeOut(duration: 1.0, delay: 0.0, completion: {
[weak self] (finished: Bool) -> Void in
guard let self = self else {return}
if self.imageView.image != nil {
print("image exist")
}
//Once the label is completely invisible, set the text and fade it back in
print(self.imageView.image as Any)
//if self.imageView.image == UIImage(named: "sunrise") {
if self.imageView.image!.pngData() == self.sunriseImage!.pngData() {
self.imageView.image = self.sunsetImage
print("sunset")
} else {
self.imageView.image = self.sunriseImage
print("sunrise")
}
// Fade in
self.imageView.fadeIn(duration: 1.0, delay: 0.0, completion: nil)
})
}
}
// MARK: - UIView (Extensions)
extension UIView {
func fadeOut(duration: TimeInterval, delay: TimeInterval, completion: ((Bool) -> Void)?) {
UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.alpha = 0.0
}, completion: completion)
}
func fadeIn(duration: TimeInterval, delay: TimeInterval, completion: ((Bool) -> Void)?) {
UIView.animate(withDuration: duration, delay: delay, options:UIView.AnimationOptions.curveEaseIn, animations: {
self.alpha = 1.0
}, completion: completion)
}
}
For this solution, the hex addresses(?) do not change for the sunrise and sunset images initialized in code:
image exist
Optional(<UIImage:0x6000020d4870 anonymous {3220, 3155}>)
sunset
image exist
Optional(<UIImage:0x6000020f0f30 named(sunset) {500, 500}>)
sunrise
image exist
Optional(<UIImage:0x6000020f0d80 named(sunrise) {3220, 3155}>)
sunset
image exist
Optional(<UIImage:0x6000020f0f30 named(sunset) {500, 500}>)
sunrise
image exist
Optional(<UIImage:0x6000020f0d80 named(sunrise) {3220, 3155}>)
sunset
image exist
Optional(<UIImage:0x6000020f0f30 named(sunset) {500, 500}>)
sunrise
image exist
Optional(<UIImage:0x6000020f0d80 named(sunrise) {3220, 3155}>)
sunset
image exist
Optional(<UIImage:0x6000020f0f30 named(sunset) {500, 500}>)
sunrise
And output on an iPhone running iOS 12.X.X (no more names, but the hex values are consistent after the first one):
image exist
Optional(<UIImage: 0x283b155e0>, {3220, 3155})
sunset
image exist
Optional(<UIImage: 0x283b11420>, {500, 500})
sunrise
image exist
Optional(<UIImage: 0x283b10f50>, {3220, 3155})
sunset
image exist
Optional(<UIImage: 0x283b11420>, {500, 500})
sunrise
image exist
Optional(<UIImage: 0x283b10f50>, {3220, 3155})
sunset
image exist
Optional(<UIImage: 0x283b11420>, {500, 500})
sunrise
Hope this has helped!
How to compare two UIImage in iOS 8
Please compare NSData object instead of comparing UIImage Object.
-(BOOL)firstimage:(UIImage *)image1 isEqualTo:(UIImage *)image2 {
NSData *data1 = UIImagePNGRepresentation(image1);
NSData *data2 = UIImagePNGRepresentation(image2);
return [data1 isEqualToData:data2];
}
Swift Image Name Compare
You cannot directly compare two images are same. You can get the images as NSDATA and then you can compare two NSDATA values are equal.
Related Topics
Get Nil When Looking for File in Subdirectory of Main Bundle
Handling an Attribute of an Xml Element in Swift
Swift 5 Coredata Predicate Using Uuid
Implement Protocol Through Extension
Loading Views into Nscontainerview with Swift
Searchbar Problem While Trying to Search Firestore and Reload the Tableview
The Right Place to Call .Removeobserver for Nsnotificationcenter = Swift Deinit()
Lottieanimationview Size Won't Change/Is Too Small (Ios/Swift)
Swift: For-In Loop Requires '[Deepspeechtokenmetadata]' to Conform to 'Sequence'
Update Nstouchbar on the Fly to Add/Remove Items Programmatically
How to Parse Firestore Fieldvalue to Date in Swift
Diffrence Between Function and Generic Function in Swift
How to Make Uicollectionview Reload Once It Receives Data from Firebase