How to compare UIImages in arrays? - ios

I'm making an application where it would be nice to be able to compare values inside one array/set.
Let's say I have constants and an array like this:
let blueImage = UIImage(named: "blue")
let redImage = UIImage(named: "red")
button.setImage(blueImage, forState: .Normal)
button2.setImage(redImage, forState: .Normal)
button3.setImage(blueImage, forState: .Normal)
var imageArray:Array<UIImage> = [button.currentImage, button2.currentImage, button3.currentImage]
Is it then possible to check/compare the values in my array and replace the red images with the blue ones.
More specifically is there a way I can check if 2/3 of the images in the array contains a specific image(blueImage), and then replace the last value(redImage) with (blueImage) so that all has the same picture.

I guess you could filter the array with something along these lines:
let filteredArray = filter(imageArray) { $0 == blueImage }
and then run a count.
You could also iterate over your array:
let countBlue = 0
for i in 0..<imageArray.count {
if imageArray[i] == blueImage {
countBlue ++
}
}
To replace an element:
imageArray[2] = blueImage

Related

UIImage not changing image because of EXC_BAD_ACCESS crash, why?

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")
}

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

Save Favorite button state with indexPath.row

I have made a favorite button for my detailViews( i have a master-detail app ) and it saves the button state generally for all cells/DetailsViews...I want if i press index's 3 cell it will save the button state only for there , if i go to index 4 it will save it individually to that row and won't save the same state to all cells.
Favorite Button:
//create a new button
let Favoritebutton: UIButton = UIButton(type: UIButtonType.custom)
//set image for button
Favoritebutton.setImage(UIImage(named: "EmptyHeart.png"), for: .normal)
Favoritebutton.setImage(UIImage(named: "FilledHeart.png"), for: .selected)
//add function for button
Favoritebutton.addTarget(self, action: #selector(self.button), for: .touchUpInside)
//set frame
Favoritebutton.frame = CGRect(x:0,y: 0,width: 35,height: 35)
Favoritebutton.isSelected = UserDefaults.standard.bool(forKey: "isSaved")
let barButton = UIBarButtonItem(customView: Favoritebutton)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
func button(sender: UIButton) {
audioPlayer.play()
let newValue = !sender.isSelected
sender.isSelected = newValue
UserDefaults.standard.set(newValue, forKey: "isSaved")
let tabItem = self.tabBarController?.tabBar.items![3]
sel_val = tabItem?.badgeValue
if(sel_val == nil){
sel_val = "0"
}
let sel_num = Int(sel_val!)
let fav: NSMutableArray = []
fav.add(barImage)
fav.add(barName)
fav.add(streetName)
if sender.isSelected {
tabItem!.badgeValue = String(format: "%d", sel_num! + 1)
favorite.add(fav)
} else {
tabItem!.badgeValue = String(format: "%d", sel_num! - 1)
favorite.remove(fav)
}
}
How can i make the button save state for each indexPath individually like i want?
This will help me finish my favorites feature so your help will be really really appreciated !
Thank you for your help !
What you want is to store array or dictionary, depends on the situation. Here is an example how to store an array How to save NSMutablearray in NSUserDefaults. I suggest to get the values from defaults when app has started and assign it to the value, so you have a local copy. Do not forget to save array back to defaults after every change, or at least when leaving the app.
EDIT:
You want to store Dictionary of bool, so that you can access values for every row. I discourage you to use indexPath, rather you should use an identifier which will be unique for a row.
These will serve as local storage for your app
let favoritesKey = "favorites"
var favorites: [Int: Bool] = [:]
This is how you obtain saved dictionary:
favorites = userDefaults.object(forKey: favoritesKey) as? [Int : Bool] ?? [:]
This is how you change your values:
favorites[index] = true / false
This is how you obtain your values:
let value = favorites[index]
This is how you save values:
let userDefaults = UserDefaults.standard
userDefaults.set(favorites, forKey: favoritesKey)

image is not set on UIButton in swift

when i pass static value in bktheme[1] then image is properly set on button.
when i already get value from NSUserDefaults and set as bktheme as under
Defaults = NSUserDefaults.standardUserDefaults()
let shape = Defaults.integerForKey("Chaperone")
print(shape) // output: 1
let str = bkthemes[shape]
keyImageTypeOne = UIImage(named: str) as UIImage?
then image is not set so, how can i set image on button
Please try below code.
If you get image name in str then only below code works.
So i want to suggest you at first print value of str in console.
Defaults = NSUserDefaults.standardUserDefaults()
let shape = Defaults.integerForKey("Chaperone")
print(shape) // output: 1
let str = bkthemes[shape]
yourButton.setImage(UIImage(named: str), forState: UIControlState.Normal)
If you get any issue then give me value of str.
your code is fine just do like
keyImageTypeOne.setImage(UIImage(named: str) as UIImage?, forState: .Normal)
You can do this:
let button:UIButton = UIButton(type: UIButtonType.System)
let image:UIImage = UIImage(named:"nope")!
button.setImage(image, forState: UIControlState.Normal)

Highlighting the correct answer in a quiz app

I'm new to iOS development and have been working through some online courses. In one of these we develop a quiz app and I'd like to improve my skills by improving the app beyond what is covered in the course.
The app uses a .json file as the 'database' of questions and answers. This .json file looks as follows...
{
"id" : "1",
"question": "Earth is a:",
"answers": [
"Planet",
"Meteor",
"Star",
"Asteroid"
],
"difficulty": "1"
}
...and just keeps going for over 500 questions.
At present, the app presents the user a question with the four possible answers. In the .json file, the first answer is always the correct answer, but the app is coded to shuffle the answers so that the correct answer is not always listed first.
The app is also coded so that the four buttons (I use four different coloured images for the buttons) displaying the answers are disabled and also dimmed in appearance after the user makes a selection, except that the button they selected is not dimmed so that their choice is highlighted.
What I would like to do is change this so that the button with the correct answer is highlighted instead, as a way of notifying the user what the correct answer was.
I'm using the following code to load the questions and answers and to shuffle the answers:
func loadAllQuestionsAndAnswers()
{
let path = NSBundle.mainBundle().pathForResource("content", ofType: "json")
let jsonData : NSData = NSData(contentsOfFile: path!)!
allEntries = (try! NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers)) as! NSArray
//println(allEntries)
}
func loadQuestion(index : Int)
{
let entry : NSDictionary = allEntries.objectAtIndex(index) as! NSDictionary
let question : NSString = entry.objectForKey("question") as! NSString
let arr : NSMutableArray = entry.objectForKey("answers") as! NSMutableArray
//println(question)
//println(arr)
labelQuestion.text = question as String
let indices : [Int] = [0,1,2,3]
//let newSequence = shuffle(indices)
let newSequence = indices.shuffle()
var i : Int = 0
for(i = 0; i < newSequence.count; i++)
{
let index = newSequence[i]
if(index == 0)
{
// we need to store the correct answer index
currentCorrectAnswerIndex = i
}
let answer = arr.objectAtIndex(index) as! NSString
switch(i)
{
case 0:
buttonA.setTitle(answer as String, forState: UIControlState.Normal)
break;
case 1:
buttonB.setTitle(answer as String, forState: UIControlState.Normal)
break;
case 2:
buttonC.setTitle(answer as String, forState: UIControlState.Normal)
break;
case 3:
buttonD.setTitle(answer as String, forState: UIControlState.Normal)
break;
default:
break;
}
At present I am using this code to check the answer:
var currentCorrectAnswerIndex : Int = 0
func checkAnswer( answerNumber : Int)
{
if(answerNumber == currentCorrectAnswerIndex)
{
// we have the correct answer
labelFeedback.text = "Correct! +1"
labelFeedback.textColor = UIColor.greenColor()
score = score + 1
labelScore.text = "score: \(score)"
SaveScore()
// later we want to play a "correct" sound effect
PlaySoundCorrect()
}
else
{
// we have the wrong answer
labelFeedback.text = "Wrong answer"
labelFeedback.textColor = UIColor.redColor()
// we want to play a "incorrect" sound effect
PlaySoundWrong()
}
In terms of highlighting the buttons I was going to use coding such as:
func resetAnswerButtons()
{
buttonA.alpha = 1.0
buttonB.alpha = 1.0
buttonC.alpha = 1.0
buttonD.alpha = 1.0
buttonA.enabled = true
buttonB.enabled = true
buttonC.enabled = true
buttonD.enabled = true
}
#IBAction func PressedButtonA(sender: UIButton) {
print("button A pressed")
buttonB.alpha = 0.3
buttonC.alpha = 0.3
buttonD.alpha = 0.3
buttonA.enabled = false
buttonB.enabled = false
buttonC.enabled = false
buttonD.enabled = false
CheckAnswer(0)
}
#IBAction func PressedButtonB(sender: UIButton) {
print("button B pressed")
buttonA.alpha = 0.3
buttonC.alpha = 0.3
buttonD.alpha = 0.3
buttonA.enabled = false
buttonB.enabled = false
buttonC.enabled = false
buttonD.enabled = false
CheckAnswer(1)
}
#IBAction func PressedButtonC(sender: UIButton) {
print("button C pressed")
buttonA.alpha = 0.3
buttonB.alpha = 0.3
buttonD.alpha = 0.3
buttonA.enabled = false
buttonB.enabled = false
buttonC.enabled = false
buttonD.enabled = false
CheckAnswer(2)
}
#IBAction func PressedButtonD(sender: UIButton) {
print("button D pressed")
buttonA.alpha = 0.3
buttonB.alpha = 0.3
buttonC.alpha = 0.3
buttonA.enabled = false
buttonB.enabled = false
buttonC.enabled = false
buttonD.enabled = false
CheckAnswer(3)
}
What I can't get my head around is how to code the app so that it highlights the correct answer? At present, the above code effectively highlights the button that was pressed by dimming the alpha of the 'other' buttons. How do I get the app to identify which 'shuffled' button contains the correct answer and highlight that one instead?
When rolling your dice, remember the index of the button containing the right answer.
Also, you may put all buttons in an array and manipulate all of them with forall loops. That makes the code much, much cleaner and gets rid of the weird variable names and the switch case.

Resources