Swift: String Concatenation for Outlet names - swift

I'm looking to reduce the number of lines in my code, I have quite a lot of label names that correspond to their values. I was wondering if there is a way of setting these values in a for-in loop or something similar. Right now I'm struggling to find a way of concatenating the label names to make them dynamic. I'm not sure if I'm able to do this in Swift, any thoughts? Thanks.
This code
LabelGiraffe1.text = "This is Giraffe 1"
LabelGiraffe2.text = "This is Giraffe 2"
LabelGiraffe3.text = "This is Giraffe 3"
LabelGiraffe4.text = "This is Giraffe 4"
LabelGiraffe5.text = "This is Giraffe 5"
To something cleaner like...
for number in 1...5 {
LabelGiraffe + /(number).text = "This is Giraffe /(number)"
}

Make an array of labels and over them:
let giraffeLabels = [LabelGiraffe1, LabelGiraffe2, LabelGiraffe3, LabelGiraffe4, LabelGiraffe5]
for (index, label) in enumerate(giraffeLabels) {
label.text = "This is Giraffe \(index + 1)"
}
You can also make giraffeLabels as stored or calculated property of your view controller.

Use an IBOutletCollection. It's effectively like putting all your outlets into an array (which is what it does in the background, I believe). You can then iterate over them, or access them by index, as you're trying to do.
More information here: http://nshipster.com/ibaction-iboutlet-iboutletcollection/

Related

Eliminate repetition in updating strings selected randomly within a state property

First, I'm very new to Swift, and coding in general. I'm trying to use the correct terminology, so I apologize if it makes no sense. Doing my best!
Ok, so there appears to be a lot of information/answers on ways to random select strings (or integers, etc) from an array without repetition. However, in my current application, I am not using an array (I kind of am but not directly related to the question). But rather a #State designation, in which the variable has an initial value (a string with a number and letter) and is later updated when a button is pushed. The string changes to a randomly selected string from my assets folder based on the file name, which will be the same word but with a different number and letter. What is the simplest way to keep from updating to strings that have already appeared?
Example of what the code looks like:
#State var relevantWord = "bird"
Button {
let randoNum = Int.random(in: 1...5)
let x = ["a", "b", "c", "d"]
let randoLet = x.randomElement()
relevantWord = "bird" + String(randoNum) + String(randoLet)
}
So, the relevantWord variable starts as "bird2c" for example, and each time the button is pushed, it will change to "bird3b" then "bird4a" etc. I just want to keep it from repeating and return nothing when the assets are depleted. Thanks!

Randomly select an array from group of "enabled" arrays

I have a set of four arrays. I also have an option to either enable or disable 3 of the 4 arrays (one is always enabled).
Is there a way to randomly decide which array to pull a value from (of the arrays indicated as enabled)?
I originally was aiming to make a master array and just append the content of the other enabled ones into it, but it proved a little harder than expected. I figured it would be easier to simply randomly select an array to pull the single value from as long as it was "enabled".
I'm currently pulling the value with a simple statement such as
If ????? {
return promptArrayA[desiredIndexA]
} else if { ?????
return promptArrayB[desiredIndexB]
} else if { ?????
return promptArrayC[desiredIndexC]
} else {
return promptArrayD[desiredIndexD]
I'm thinking if I had a "randomizer" that chose one of the enabled arrays, then I can use that as a constraint in an If Statement.
I'm fairly new to Swift so any help is much appreciated. Thank you
You can get the array randomly by doing:
let enabledArrays = [promptArrayA, promptArrayB, promptArrayC, promptArrayD]
let randomIndex = Int.random(in: 0..<enabledArrays.count)
let randomArray = enabledArrays[randomIndex]
return randomArray[desiredIndex]

Localization for the words "minutes" and "seconds" in countDownTimerLabel

I localised almost all labels and buttons. However, when I localise my timerLabel, the words "min" and "sec" are not translated in other language. Here's the timer function.
enter image description here
In order to localise countDownLabel, I used this localisation method below.
func setUpTranslation() {
countDownLabel.text = NSLocalizedString("CountDown", comment: "")
}
I tried to set "CountDown" key for the countDownLabel in Localizable.strings(Spanish) like these below one by one. But they didn't work.
"CountDown" = "(%d)min(%d)seg"
"CountDown" = "(minutes)min(seconds)seg"
"CountDown" = "%dmin%dseg"
"CountDown" = "\(%d)min\(%d)seg"
Would you tell me whether there is any other sign that I need to add to successfully translate those words or not?

How to get the index of randomElement

I want to know how I can get the index of an array in Swift if I use randomElement.
Example :
I've an array from a JSON file. After each click on a button, I want to change the label by a value from the array.
I want to looping through the array for print the value and delete this after the display. The problem is I don't see how I get the current value to delete her.
if let rand = myArray.randomElement() {
myLabel.text = rand.question
}
I've seen more options to make a random in array but with after reading some articles for Swift 4.2, the best practice is to use randomElement().
A simple solution is to get a random index
if let index = myArray.indices.randomElement() {
myLabel.text = myArray[index].question
}

generating Localizable.strings creates strange output

When I use genstrings -o en.lproj *.m it generates the Localizable.strings file with entries in this structure:
/* this is the text: %# ID: %02X */
"this is the text: %# ID: %02X" = "this is the text: %1$# ID: %2$X";
Please notice that it makes from %# -> %1$#
Why is this? I always have to change it back to %# manually.
Thanks
Did you use the "-j" option? It produces java localized string (which have the format like %1$#).
[EDIT]
Sorry, looked at the wrong manual page. Please use the option -noPositionalParameters to turn off generation of positional parameters. -> Info's here
You don't need to change it back, since %1$# refers to the first argument given to your format string.
Actually, in a case different from yours, it might happen that the order of the arguments changes from a translation to another. For example, if your code uses a format to display some player property value like:
let fmt = NSLocalizedString("Player property value", comment: "The player property value")
String(format:fmt, playerName, playerProperty, value)
You might have in the "en.lproj/Localizable.strings":
/* The player property value */
"Player property value" = "Player %1$#'s %2$# is %3$d"
and in the "fr.lproj/Localizable.strings":
/* The player property value */
"Player property value" = "Le %2$# du joueur %1$# is %3$d"
or:
/* The player property value */
"Player property value" = "Le joueur %1$# a %3$d points de %2$#"