I am working on a image quiz. I have a button that will display either the correct image or the wrong image if there is no correct image. The unique question number comes from an array.
if (questionlist[1]correct = [UIImage imageNamed:#"questionlist[1]correct.png"]) {
Answer4.setImage(UIImage(named: "\(questionlist[1])correct.png"), forState: UIControlState.Normal)
} else {
Answer4.setImage(UIImage(named: "\(questionlist[1])fourthwrong.png"), forState: UIControlState.Normal)
}
Okay so if I'm understanding your questionList array is simply an array of numbers? So questionList = [1,2,3,etc]? In that case, you may want to try something like:
let imageName = "\(questionList[1])wrong.png" //for instance 2wrong.png
if (UIImage(named: imageName) == nil) { // no wrong image exists
imageView.image = UIImage(named: "\(questionList[1])correct.png")
} else {
imageView.image = UIImage(named: "\(questionList[1])wrong.png")
}
Of course this is assuming a correct image exists. It's unclear what you're after, some more information/more code would help.
Related
I'm trying to check the image name in the UIButton like this:
#IBAction func buttonTapped(_ sender: Any) {
if xcodeButton.currentImage == UIImage(named: "xcode") {
print("xcode image")
}
}
But I have a break point in the if statement and this is the output:
po xcodeButton.currentImage
▿ Optional<UIImage>
- some : <UIImage:0x6000011a93b0 named(main: xcode) {500, 500}>
but if I compare it
po xcodeButton.currentImage == UIImage(named: "xcode")
false
Any of you knows why the comparison is returning false? or how can compare the name of the image in UIButton?
I'll really appreciate your help.
You should use isEqual(_:) From Docs scroll to Comparing Images section
let image1 = UIImage(named: "MyImage")
let image2 = UIImage(named: "MyImage")
if image1 != nil && image1!.isEqual(image2) {
// Correct. This technique compares the image data correctly.
}
if image1 == image2 {
// Incorrect! Direct object comparisons may not work.
}
None of these solutions were working for me. So I used pngData to compare images:
let image1Data = UIImage(named: "MyImage")?.pngData()
let image2Data = UIImage(named: "MyImage")?.pngData()
if image1Data == image2Data {
// It compares data correctly
}
I have set a placeholder image for my image views. The user can change these to a photo from their library. Once they have done this, they can then upload these images to a database. The user can upload a single image or many, either way, they are uploaded as an [UIImage]. However, I do not want the placeholder images to be uploaded.
I have managed to achieve this, but in a very ungraceful manner. I have done this by firstly subclassing UIImageView, adding a property called isSet and setting all my image views to this class:
class ItemImageViewClass: UIImageView {
//keeps track of whether the image has changed from the placeholder image.
var isSet = Bool()
}
and then when the image has been set after the user has selected an image, the isSet property is set to true.
To check if the image in the image view has been changed from the placeholder image (i.e. isSet == true) I used the following code:
var imageArray: [UIImage]? = nil
if imageViewOne.isSet {
guard let mainImage = imageViewOne.image else {return}
if (imageArray?.append(mainImage)) == nil {
imageArray = [mainImage]
}
}
if imageViewTwo.isSet {
guard let imageTwo = imageViewTwo.image else {return}
if (imageArray?.append(imageTwo)) == nil {
imageArray = [imageTwo]
}
}
guard imageArray != nil else {
print("imageArray is nil")
alertMessage("Hey!", message: "Please add some images!")
return
}
When at least one image has been selected, the array will be saved to the database.
This seems like a very messy way to do it; subclassing UIImageView and having to check that each image has changed using a series of if statements. Is there a more elegant way to achieve this? Thanks
There is a solution by extending UIImageView to avoid subclassing. And, using filter and flatMap to by pass the if-statements. This requires that you use the same reference to the placeholder image for each UIImageView.
// In this example, the placeholder image is global but it doesn't have to be.
let placeHolderImage = UIImage()
extension UIImageView {
// Check to see if the image is the same as our placeholder
func isPlaceholderImage(_ placeHolderImage: UIImage = placeHolderImage) -> Bool {
return image == placeHolderImage
}
}
Usage:
let imageViewOne = UIImageView(image: placeHolderImage)
imageViewOne.isPlaceholderImage() // true
let imageViewTwo = UIImageView()
imageViewTwo.isPlaceholderImage() // false
let imageViewThree = UIImageView()
imageViewThree.image = UIImage(named: "my-image")
imageViewThree.isPlaceholderImage() // false
Filter and map for images that are not placeholders or nil:
let imageArray = [imageViewOne, imageViewTwo, imageViewThree].filter
{ !$0.isPlaceholderImage() }.flatMap { $0.image }
print(imageArray) // imageViewThree.image
If the extension does not work for your requirements, I would definitely consider "filter and flatMap" to avoid that if-statement.
I would recommend creating a new UI component for your needs with a background UIImageView(placeholder) and an optional foreground UIImageView (user selected). Then just check for the existence of the optional foreground UIImageView as you can rely upon this being the UIImageView containing the user chosen image.
I have a Core Data entity which has logo as one of its attributes - I need to check the count of logo, so I can properly set an image view in the cell (i.e. avoid a crash when a new company is added and doesn't have a logo). With a hardcoded array of, say, logos, it's as simple as logos.count, but I'm not sure how to perform the same check on a Core Data entity. What's the best way of doing this?
DispatchQueue.main.async {
if /*What to count?*/.count >= indexPath.row + 1 {
cell.logoView.image = UIImage(named: (company.value(forKey: "logo") as? String)!)
} else {
cell.logoView.image = UIImage(named: "noImage")
}
}
Based on what I can see from your current setup, the following should be fine:
DispatchQueue.main.async {
if let logo = company.value(forKey: "logo") as? String {
cell.logoView.image = UIImage(named: logo)
} else {
cell.logoView.image = UIImage(named: "noImage")
}
}
Let me know if this makes sense.
Everything I google turns up answers about ALAsset's.
I have an images.xcassets folder and a bunch of assets in there.
I want to know if an asset exists in there based on a string.
E.g. if(images.xcassets.contains("assetName") == true)
Do you know how I can check if an asset exists based on a string?
This is one way to check it.
NSString *someString = #"SomeStringFromSomwhere";
if ([UIImage imageNamed: someString])
{
//the image exists..
}
else
{
//no image with that name
}
Just a bit more practical answer: Swift
if let myImage = UIImage(named: "assetName") {
// use your image (myImage), it exists!
}
Check whether image exist or not : Swift 3
if (UIImage(named: "your_Image_name") != nil) {
print("Image existing")
}
else {
print("Image is not existing")
}
I ended up with some combination of both and turned it into a function to use throughout my code. I also want to return a default image if the one provided is missing. (Swift 4 version)
func loadImage (named: String) -> UIImage {
if let confirmedImage = UIImage(named: named) {
return confirmedImage
} else {
return UIImage(named: "Default_Image.png")
}
}
Then to load the image into something like a button you do something like this.
buttonOne.setImage(loadImage(named: "YourImage.png"), for: .normal)
For Swift, this is what I ended up using to assign either an existing asset or a default system image:
myImageView.image = UIImage(named: "myAssetName") ?? UIImage(systemName: "photo")
// When former is nil, assigns default system image called "photo"
I'm creating a UIButton with an image,
I have written the below code for that:
let btnImg=UIButton.buttonWithType(UIButtonType.Custom) as UIButton
let img = UIImage(named: "turn_left") as UIImage
btnImg.setTitle("Turn left", forState: UIControlState.Normal)
btnImg.setImage(img, forState: UIControlState.Normal)
btnImg.frame = CGRectMake(10, 150, 200, 45)
self.view.addSubview(btnImg)
But I got the error below at let img = UIImage(named: "turn_left") as UIImage:
Swift Compiler error:
Downcast from 'UIImage?' to 'UIImage' only unwraps optionals; did you mean to use '!'?
As error Says You have to use '!' ,
Try Below code,
let img = UIImage(named: "turn_left") as UIImage! // implicitly unwrapped
OR
let img : UIImage? = UIImage(named: "turn_left") //optional
Edit
After creating img you need to check it for nil before using it.
You can always do it in an 'if let' but note the difference in syntax depending on the version of swift.
Swift < 2.0:
if let img = img as? UIImage {
Swift 2.0:
if let img = img as UIImage! {
Note the position of the exclamation
If the UIImage initialiser cannot find the file specified (or some other error happened), it will return nil, as per Apple's documentation
Return Value
The image object for the specified file, or nil if the method could not find the specified image.
So you need to put checks in:
let img = UIImage(named: "turn_left")
if(img != nil) {
// Do some stuff with it
}
You don't need to cast a UIImage to a UIImage, that's a waste.
Edit: Full code
let img = UIImage(named: "turn_left")
if(img != nil) {
let btnImg = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
btnImg.setTitle("Turn left", forState: UIControlState.Normal)
btnImg.setImage(img, forState: UIControlState.Normal)
btnImg.frame = CGRectMake(10, 150, 200, 45)
self.view.addSubview(btnImg)
}
You may want to put an else in to set the button to a shape or something else that is more likely to work in the case "turn_left" doesn't exist.
Since UIImage(named:"something") returns an optional (because it could be nil if the methods doesn't find an appropriate image the best this is not to explicitly unwrap the result (otherwise your app will crash) but to check for the result immediately with something like that:
if let image = UIImage(named: "something"){
// now you can use image without ? because you are sure to have an image here!
image.description
}
// continue your code here using the optional power of swift's vars! :)
The approach is the following: If the image is optional means that it can be null. Functions that takes in input an optional can handle that, otherwise they usually have unexpected behavior. The UIImage(named:) can return nil and you HAVE to handle this. If you explicitly unwrap it you could have problems later.
With if let something = ... something will be automatically unwrapped in runtime and you can use it safely.