UIImage not changing image because of EXC_BAD_ACCESS crash, why? - ios

I have this conditional that results in a UIImageView being changed depending one what side a coined "flipped" (Int.rand(0...1). I am not sure why it is crashing at this particular spot, as before the program gets to this point it could change the exact same UIImageView with another image asset. The image asset I want to change it to does exist in the asset folder. It's just confusing why it is crashing at this particular instance.
func changeField(coin: Int){
lowerField.isUserInteractionEnabled = false
upperField.isUserInteractionEnabled = false
firstP1.isHidden = true
firstP2.isHidden = true
if coin == 0{
lowerField.image = UIImage(named: "Red_Attacker")
upperField.image = UIImage(named: "Blue_Defender")
if userSettings.float(forKey: "Timer_Slider") == 0{
gameP1()
}else{
startTimer(slider_Value: userSettings.float(forKey: "Timer_Slider"), coin: coin)
}
}else{
lowerField.image = UIImage(named: "Blue_Defender")
upperField.image = UIImage(named: "Red_Attacker")
if userSettings.float(forKey: "Timer_Slider") == 0{
gameP2()
}else{
startTimer(slider_Value: userSettings.float(forKey: "Timer_Slider"), coin: coin)
}
}
}
this shows where it specifically throws the exception
Anyone have any idea why it is crashing at this spot? Would appreciate the help!

first make sure that you have an image with this name
second thing try to put it in dispatchQueue:
DispatchQueue.main.async {
lowerField.image = UIImage(named: "Red_Attacker")
upperField.image = UIImage(named: "Blue_Defender")
}
DispatchQueue.main.async {
lowerField.image = UIImage(named: "Blue_Defender")
upperField.image = UIImage(named: "Red_Attacker")
}

Related

Swift 5 or up - Image view on pickerview

My images from "2.jpg" to "7.jpg" shows but the first image("1.jpg") on my simulator. what do I need to change?
var imageFileName = ["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg","7.jpg"]
for i in 0 ..< MAX_ARRAY_NUM {
let image = UIImage(named: imageFileName[i])
imageArray.append(image)
lblImageFileName.text = imageFileName[0]
imageView.image = imageArray[0]
enter image description here
enter image description here
I think you should change below two lines
lblImageFileName.text = imageFileName[0]
imageView.image = imageArray[0]
to,
lblImageFileName.text = imageFileName[i]
imageView.image = imageArray[i]
as you used variable i to represent index

How to display an image if variable equals a special number using swift 3?

I have three pictures (lvl1.png, lvl2.png, lvl3.png) and an variable (let level = 1). What should I do to display an image named 'lvl2' if level = 2, and when level = 3 I need to show the last image (lvl3.png)?
you can use:
let image = UIImage(named: "lvl\(level).png")
or
let image: UIImage!
switch level {
case 1:
image = UIImage(named: "lvl1.png")
case 2:
image = UIImage(named: "lvl2.png")
case 3:
image = UIImage(named: "lvl3.png")
default:
image = UIImage()
}
avatar.image = image
you can try
imgName = "lvl" + String(lavel)
imageView.image = UIImage(named: imgName)
Another alternative is to create a method that returns an image, like so:
func imageFor(level: Int) -> UIImage? {
let image = UIImage(named: "lvl\(currentLevel)")
return image
}
Usage:
var currentLevel = 1
let image = imageFor(level: currentLevel)
You can try
var level = 1 {
didSet {
self.imageview.image = UIImage(named: "lvl\(level)")
}
}
when you change the level the imageView will change automatically

How to check if a button has this image

I want to check if myButton has a named image.
I try this but it doesn't work
if (myButton.currentImage?.isEqual(UIImage(named: "ButtonAppuyer.png")) != nil){
print("YES")
} else {
print("NO")
}
and this too doesn't work
if myButton.currentImage?.isEqual(UIImage(named: "ButtonAppuyer.png")){
print("YES")
} else {
print("NO")
}
Here is what I came up with in Swift 3.0.
if let myButtonImage = myButton.image(for: .normal),
let buttonAppuyerImage = UIImage(named: "ButtonAppuyer.png"),
UIImagePNGRepresentation(myButtonImage) == UIImagePNGRepresentation(buttonAppuyerImage)
{
print("YES")
} else {
print("NO")
}
This could be cleaned up a lot.
extension UIButton {
func hasImage(named imageName: String, for state: UIControlState) -> Bool {
guard let buttonImage = image(for: state), let namedImage = UIImage(named: imageName) else {
return false
}
return UIImagePNGRepresentation(buttonImage) == UIImagePNGRepresentation(namedImage)
}
}
Then use it
if myButton.hasImage(named: "ButtonAppuyer.png", for: .normal) {
print("YES")
} else {
print("NO")
}
in swift 4.2 and Xcode 10.1
buttonOne.image(for: .normal)!.pngData() == UIImage(named: "selected")!.pngData()
You can convert the button's image and the named image to NSDatas and compare the two data objects:
let imgData1 = UIImagePNGRepresentation(buttonImage)
let imgData2 = UIImagePNGRepresentation(namedImage)
let equal = imgData1 == imgData2
Note that this will only work if the two images are completely identical (e.g. come from the same source file); if one is a scaled down version of the other, it won't work.
Also, it should be mentioned that this can be a pretty expensive operation and should not be run frequently.
There is no way to retrieve the image name from a UI element. You will need to store the value you want to retrieve in another location.
For instance, you could create a custom subclass of UIButton that contains an additional property to store the image name or other identifying data.
if let ButtonImage = myButton.image(for: .normal),
let Image = UIImage(named: "ButtonAppuyer.png"),
UIImagePNGRepresentation(ButtonImage) == UIImagePNGRepresentation(Image)
{
print("YES")
} else {
print("NO")
}
if myCell.followButton.currentImage.isEqual(UIImage(named: "yourImageName")) {
//do something here
}

Swift : Avatar image is mandatory in swift code

By default "no-profile-image" is set to imageview, User should upload the profile picture mandatory while registration, otherwise user should not allow to navigate to next screen.Any help is appreciable.
Here is my code
lazy var profileLogo:UIImageView = {
let profileLogo = UIComponentFactory.appImageView(UIImage(named: "no-profile-image")!, contentMode: .ScaleToFill, cornerRadius: LayoutService.width(15))
profileLogo.userInteractionEnabled = false
return profileLogo
}()
func nextButtonPressed() {
let noImage = UIImage(named: "no-profile-image")
if self.mainView.profileLogo.image == nil && self.mainView.profileLogo.image == noImage{
displayAlert("", message: "profile picture is mandatory, please upload it")
}
}

tableView images randomly disappearing

I am modifying my paid for app to a free with IAP.
Some group types are free and some will need to be paid for.
On the tableView controller, there is a padlock UIImageView that displays each "locked" item if it is a part of a locked group.
When someone buys that group, or all, that padlock is meant to disappear. This padlock is not a part of the code that prevents the user from seeing the details as I have that code somewhere else and it works fine.
Initially, "Padlock" displays accurately. However, If I scroll up and down on the tableView, the padlocks will randomly disappear.
How to prevent this?
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
//
// We need to fetch our reusable cell.
//
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: Resource.SpeciesCell)!
//
// Get all of the components of the cell.
//
let specieImage: UIImageView = cell.viewWithTag(Resource.SpeciesImageTag) as! UIImageView
let specieName: UILabel = cell.viewWithTag(Resource.SpeciesNameTag) as! UILabel
let specieGenus: UILabel = cell.viewWithTag(Resource.SpeciesGenusTag) as! UILabel
let specieFamily: UILabel = cell.viewWithTag(Resource.SpeciesFamilyTag) as! UILabel
// Set our name, family and genus labels from our data.
//
specieName.text = self.species[(indexPath as NSIndexPath).row].specie
specieFamily.text = ""
specieGenus.text = self.species[(indexPath as NSIndexPath).row].speciesSubgroup
// **** Adding Padlock Begins HERE ****
let padLock: UIImageView = cell.viewWithTag(Resource.SpeciesCategoryLabelTag) as! UIImageView
padLock.image = UIImage(named: "PadlockIcon")
padLock.alpha = 0.7
let speciesGroupFreeArray: Array<String>
let speciesGroupVertebratesArray: Array<String>
let speciesGroupInvertebratesArray: Array<String>
speciesGroupFreeArray = ["eels", "Mammals", "Annelids", "Bivalvians", "Cephalopods", "Cool oddities", "Crustacean", "Echinoderms", "Hydrozoans", "Isopods"]
speciesGroupVertebratesArray = ["Fish", "Sharks", "Rays", "Reptilia", "Syngnathiformes"]
speciesGroupInvertebratesArray = ["Corals", "Gastropods"]
let fishesPurchased = UserDefaults.standard.bool (forKey: "ReefLife5Fishes")
let sharksPurchased = UserDefaults.standard.bool (forKey: "ReefLife6Sharks")
let nudisPurchased = UserDefaults.standard.bool (forKey: "ReefLife7Nudis")
let turtlesPurchased = UserDefaults.standard.bool (forKey: "ReefLife8Turtles")
let seahorsesPurchased = UserDefaults.standard.bool (forKey: "ReefLife9Seahorses")
let coralsPurchased = UserDefaults.standard.bool (forKey: "ReefLife4Corals")
let vertebratesPurchased = UserDefaults.standard.bool (forKey: "ReefLife3Vertebrates")
let invertebratesPurchased = UserDefaults.standard.bool (forKey: "ReefLife2Invertebrates")
let fullPurchased = UserDefaults.standard.bool (forKey: "ReefLife1Full")
let categoryName = self.species[(indexPath as NSIndexPath).row].group
if fullPurchased == true {
padLock.isHidden = true
} else if speciesGroupVertebratesArray.contains(categoryName) {
if vertebratesPurchased == true {
padLock.isHidden = true
} else {
if categoryName == "Fish" {
if fishesPurchased == true{
padLock.isHidden = true
} else{
}
} else if (categoryName == "Sharks" || categoryName == "Rays" ) {
if sharksPurchased == true{
padLock.isHidden = true
} else{
}
} else if categoryName == "Syngnathiformes" {
if seahorsesPurchased == true{
padLock.isHidden = true
} else{
}
} else if categoryName == "Reptilia" {
if turtlesPurchased == true{
padLock.isHidden = true
} else{
}
}
}
} else if speciesGroupInvertebratesArray.contains(categoryName) {
if invertebratesPurchased == true {
padLock.isHidden = true
} else {
if categoryName == "Corals" {
if coralsPurchased == true{
padLock.isHidden = true
} else{
}
} else if categoryName == "Gastropods" {
if nudisPurchased == true{
padLock.isHidden = true
} else{
}
}
}
}
if speciesGroupFreeArray.contains(categoryName) {
padLock.isHidden = true
}
// **** Adding Padlock Ends HERE ****
//
// We now need to set our photo. First, we need to fetch the photo based on our specie
// id.
//
let photos = AppDelegate.getRLDatabase().getSpeciePhotos(self.species[(indexPath as NSIndexPath).row].id)
//
// Set the image for our UIImageView.
//
if photos.isEmpty != true
{
specieImage.clipsToBounds = true
specieImage.contentMode = .scaleAspectFill
specieImage.image = UIImage(named: photos[0].name)
// specieImage.image = UIImage(named: photos[0].name)?.resizeTo(specieImage.bounds)
}
else
{
specieImage.image = UIImage(named: Resource.UnknownImage)?.resizeTo(specieImage.bounds)
}
//
// Return our new cell.
//
return cell
}
Please try replace this
if speciesGroupFreeArray.contains(categoryName) {
padLock.isHidden = true
}
to
padLock.isHidden = speciesGroupFreeArray.contains(categoryName)
Your code only ever sets padlock.isHidden = true. If you get a recycled cell where the padlock is already hidden, there's nothing to unhide it.
You need to explicitly set the padlock isHidden state in all cases.
Given your somewhat contorted code for setting the isHidden property, the simplest way to fix your current code would be to set padlock.isHidden = false At the beginning of your cellForRowAt() method. Then, if none of the cases set isHidden to true, it will always be unbidden, even in a case where you are reconfiguring a recycled cell where the padlock was hidden.
EDIT:
This a key take-away for managing table views and collection views in iOS. Always assume that a cell comes to you with all views set to a non-default state. Your code always needs to explicitly set every view to a specific state.
Think of a table view cell as a paper patient info form at a doctor's office where the office recycles the forms, and doesn't erase the info left by the previous patient. You always have to erase the info left by the previous patient. If you don't have an allergy to peanuts, it's not enough to simply not check that box. You have to erase the previous check marks and other info, or the previous patient's info will get mixed up with yours.
That's what's happening with your padlock.isHidden state. You're assuming it starts out in the default state, but it may not.

Resources