How to generate Labelname from a variable? (how to cast a string to UILabel) - swift

I want to refer to a label based on the title of the button pressed.
I have a plenty of buttons, that I connected together in a single action. I want to be able to refer to only one label, that corresponds to the name of button pressed.
The Label names are: aLabel, bLabel, cLabel ...
The buttons pressed are titled "a", "b", "c"...
I ame creating the string with name of the label i want to refer to, but I can't use it as label name to change this particular label values.
I want to use this string to refer to the corresponding label, to change it title, color, and so on.
I tried, casting, looking for a function that changes strings into UILabels. I was also thinking about an array with pointers to the Labels, but I didn't succed even with establishing a pointer to a single Label...
//My code
#IBOutlet weak var a: UIButton!
#IBOutlet weak var b: UIButton!
#IBOutlet weak var c: UIButton!
#IBOutlet weak var aLabel: UILabel!
#IBOutlet weak var bLabel: UILabel!
#IBOutlet weak var cLabel: UILabel!
var currentLabel : String
#IBAction func FieldDisplay(_ sender: UIButton) {
currentLabel = sender.currentTitle! + "Label"
currentLabel.text = "OK"
}
//what I tried
(UILabel)currentLabel.text = "OK"
currentLabel = currentLabel.to.UIlabel

When interface objects are associated in multiple pairs like this — a series of button–label pairs, as you have it — there are two approaches commonly used. One is to assign each pair a tag. For example, in the storyboard, the first button would have tag 1, and the first label would have tag 101. Then the second button would have tag 2, and the second label would have tag 102. And so on.
So now in your IBAction function you look at the tag of the sender, add 100 to it, and call viewWithTag on your view to find the corresponding label.
The other possibility is to use outlet collections. Instead of three button outlets you have one array-of-button outlet; so too for the labels. Now in your IBAction function you get the firstIndex of the button in its array; that, if you've set this up correctly, is the index of the corresponding label in its array.

Remove all outlets and create 2 collections
#IBOutlet var allBts: [UIButton]!
#IBOutlet var allLbls: [UILabel]!
then hook all labels / btns to each , and set a tag for each group ( lbl1 && btn1 tag = 0 , lbl2 && btn2 tag = 1 and so on)
#IBAction func FieldDisplay(_ sender: UIButton) {
allLbls[sender.tag].text = sender.currentTitle! + "Label"
}

You can use value(forKey:) method
#IBAction func buttonTapped(_ sender: UIButton) {
if let currentLabel = value(forKey: sender.currentTitle! + "Label") as? UILabel {
currentLabel.text = "OK"
}
}
https://developer.apple.com/documentation/objectivec/nsobject/1412591-value

Related

Clear all Text Fields button Swift

I'm making an app where users put numbers into 4 different textfields and it does something with them on the backend. Right now if they want to change those numbers they have to go back and delete them all and retype them or close the app and reopen it to have all the text fields blank again.
I want to add a button to the bottom of the app that says something like Clear Text and it will clear all 4 textfields.
I've tried looking it up but couldn't find anything like this, Only to make a clear text button appear when editing that text field. I'm looking to clear 4 text fields when a Button is clicked.
This should work:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBOutlet var field1: UITextField!
#IBOutlet var field2: UITextField!
#IBOutlet var field3: UITextField!
#IBOutlet var field4: UITextField!
#IBAction func buttonThatClears(_ sender: UIButton) {
field1.text = ""
field2.text = ""
field3.text = ""
field4.text = ""
field1.becomeFirstResponder()
}
}
Likely will look something like this:
Select the Attributes inspector for the textField.
In the first section, you have Clear button
Below, select Clear when editing begins.

How to create an effect to highlight correct answer

I am learning Swift, and I am throwing myself in the deep end to force myself to learn the language. I have a nephew who is a baby and thought to make an app to help him learn numbers.
The app is designed to set a set number of buttons on the screen like the one provided below. I have the code to play Directions, which tells the user which number to select. A-N14a, the audio file, says to click the 4. The Done button is set to move to the next screen.
What I am asking is that if I want 4 to be pressed, and they press the 9, I want to know how to implement a feature to give a hint to click the number 4? The idea is to change the background to a button, but I don't know how to implement the feature. I am also open to other ideas. As a note, I do not know what to do, and I'm trying to learn, so the code provided is probably very simplistic and is at the beginning stages.
Below is an image of the screen and the code for that page.
ScreenShot of Page
import UIKit
import AVFoundation
class Intervention_Numerals1: UIViewController {
#IBOutlet weak var Directions: UIButton!
#IBOutlet weak var Done: UIButton!
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
setUpElements()
//Audio Test
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "A-N14a", ofType:"mp3")!))
audioPlayer.prepareToPlay()
} catch {
print(error)
}
}
func setUpElements() {
// Style the elements
Utilities.styleFilledButton(Directions)
Utilities.styleFilledButton(Done)
}
#IBAction func Play(_ sender: Any) {
audioPlayer.play()
}
}
Please let me know any tips or advice or links to similar questions, even though I could not find any on my own.
Here's what I would do:
Record the sound "Tap the number" and then the sounds for the numbers 0 through 9. Name the number sounds "0.mp3" through "9.mp3"
Create a storyboard with 4 buttons on it (like the picture you posted.)
Set up button IBOutlets buttonA - buttonD. Put those buttons into an array:
let buttonsArray = [buttonA, buttonB, buttonC, buttonD]
Fill an array with the numbers 0-9. Shuffle it. Remove 4 values put them into an array "buttonValues" (use the method removeLast().) The code to generate non-repeating values from 0-9 might look like this:
var randomNumbers = [Int]() //Define an array to hold random Ints
var lastValueReturned: Int?
//Function to return a random Int. It won't return the same value twice
func randomNumber() -> Int {
//Remove and return an item from the array
var result: Int
repeat {
//If the array is empty, fill it with the shuffled numbers 0...9
if randomNumbers.isEmpty {
randomNumbers += Array(0...9).shuffled()
}
result = randomNumbers.removeLast()
} while result == lastValueReturned
lastValueReturned = result
return result
}
Loop through your array of buttonValues and install the string for each number as the title of one of your buttons:
for index = 0...3 {
buttonsArray[index].setTitle("(buttonValues[index])", forSate: .normal)
}
Pick an index 0-3 to be the "correct" number.
let indexToPick = Int.random(in: 0...3)
Look up that value in buttonValues, and use it to pick a sound file to play:
let numberToPick = buttonValues[indexToPick]
let soundName = "\(numberToPick).mp3"
Load and play the "tap the number" sound, and then Load and play the sound for the selected number (soundName).
When the user taps a button, have the IBAction method use the sender parameter that is passed to it, and look in the array of buttons, buttonsArray, to see which button index was tapped.
If it is the correct button, take the success action.
If the tapped button index is not indexToPick, do an animation that changes the background color of the button at indexToPick, or the button's border width, or something, and then animates it back to normal. (Look at the UIView animate(duration:) family of methods for how to animate the button's background color. Use the form that takes an options: parameter, and set the .autoreverse option.)
If you're a newbie to iOS development, figuring out how to animate your correct answer button could be a challenge. I created a sample project that just animates one of 4 random buttons: https://github.com/DuncanMC/ButtonAnimation.git
The code for that project is as follows:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var buttonA: UIButton!
#IBOutlet weak var buttonB: UIButton!
#IBOutlet weak var buttonC: UIButton!
#IBOutlet weak var buttonD: UIButton!
//Define an empty array to hold buttons.
var buttonsArray = [UIButton]()
override func viewDidLoad() {
super.viewDidLoad()
//Put our button outlets into an array so we can reference them by index.
buttonsArray = [buttonA, buttonB, buttonC, buttonD]
//Give our buttons a cornerRadius so they look rounded when we add a border and fill color
for button in buttonsArray {
button.layer.cornerRadius = 10
}
}
#IBAction func handleAnimateButton(_ sender: UIButton) {
sender.isEnabled = false
//Pick a random button
let button = buttonsArray.randomElement()!
//Create an auto-reversing animation that fills the button with cyan, and draws a border around it.
//(Showing the border won't fade in and out, but it doesn't really matter)
UIView.animate(withDuration: 0.25,
delay: 0,
options: [.autoreverse, .curveEaseInOut],
animations: {
button.backgroundColor = .cyan
button.layer.borderWidth = 1.0
}, completion: {
success in
button.backgroundColor = .clear
sender.isEnabled = true
button.layer.borderWidth = 0
})
}
}
I would do as follows:
1. Create as many IBOutlets as your numbers (I suppose 0-9 for your example?) and link them to your buttons - E.g.
#IBOutlet weak var Button1: UIButton!
#IBOutlet weak var Button2: UIButton!
// Create as many as you need - Probably 10?
2. Create an IBAction and link it to all your buttons, with this code
#IBAction func checkCorrectAnswer(_ sender: UIButton) {
let arrayOfButtons:[UIButton] = [Button1, Button2] // Here you add all your buttons
let buttonTitle = sender.title(for: .normal)!
if buttonTitle == "YOUR CORRECT ANSWER" { //You have to substitute "YOUR CORRECT ANSWER" with the right string value
sender.backgroundColor = .green
} else {
sender.backgroundColor = .red
for i in arrayOfButtons {
if i.titleLabel?.text == "YOUR CORRECT ANSWER" { i.backgroundColor = .orange }
}
}
}
Enjoy!

How can I create a function for multiple labels in a stack?

I have 3 labels and I want to generate random numbers for each of them. I use GKRandomSource class in function, thats ok. The problem is, if I want to have much more labels (ie. 30) and all with same action, I need to reference all labels one by one to IBAction, I need to state all labels one by one in func code… I’ve been searching for a shorter way, maybe put them all in 3 stacks (10 labels for each stacks) and trigger, but I got nothing. I tried outlet collections (as we use in UIButtons) but it doesn’t let me to change label text.
How can I use a function for multiple labels with no-repeat?
Example;
let allNumbers = [Int](1...99)
var shuffledNum = [Int]()
#IBOutlet weak var labelOne: UILabel!
#IBOutlet weak var labelTwo: UILabel!
#IBOutlet weak var labelThree: UILabel!
func generateNumbers() {
shuffledNum = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: allNumbers) as! [Int]
let threeNumbers = shuffledNum.prefix(3).sorted()
labelOne.text = String(threeNumbers[0])
labelTwo.text = String(threeNumbers[1])
labelThree.text = String(threeNumbers[2])
}
you can make the array of UILabel's and put all the outlets in the same array then you can use for loop to do operations on each of them.
for example:
#IBOutlet var formLabels: [UILabel]!
and can do as:
formLabels.forEach { label in
label.text = ""//put your random number function here
}
see its working after adding both outlets I have also shown the connection in the storyboard the connection exists

How to use random variable to choose correct button in swift

The title might not be the best explanation of what I want but I couldn't think of a better way to describe it.
#IBOutlet var button0: UIButton!
#IBOutlet var button1: UIButton!
#IBOutlet var button2: UIButton!
var num = (arc4random()%3);
basically I want to use the variable 'num' to choose which button and make it hidden based off the random number. Is there a way to use the variable in a a simple line like "button(num).hidden = true" or something like that?
[button0, button1, button2][num]
Basically, all you want to do is create an array of UIButtons!, and then set array[num].enable = false.
you can basically store your buttons into a array of UIButton, and then use this array randomly.
Code
self.buttons.append(button0)
self.buttons.append(button1)
self.buttons.append(button2)
self.buttons[Int(num)].hidden = true
var num = Int(arc4random_uniform(3))
let buttons:[UIButton] = [button0,button1,button2]
buttons[num].hidden = !buttons[num].hidden
Create an array that stores all your UIButtons
var buttonsArray: [UIButton]!
Access one of the UIButtons from the Array randomly and hide the accessed UIButton
var randomNum: Int = Int(arc4random()%3)
var button = buttonsArray[randomNum]
button.hidden = true

Swift: Generate Identifier for Variable

I have a large list of NSButtons (80+) that I assign to an array. I've used a numbering scheme to name them and I'd like to generate the identifiers for them instead of calling them directly by name one at a time.
#IBOutlet weak var button120: NSButton!
#IBOutlet weak var button121: NSButton!
var buttons [NSButton]()
Currently (in ViewDidLoad()) I'm doing the equivalent of:
buttons = [ button120, button121 ]
I'd prefer to do something like:
for index in 120...121 {
buttons.append("button\(index)".toIdentifier)
}
Can this be done in Swift?
This might be an easier solution, view is the parent view of the buttons
let buttons = view.subviews.filter { $0 is NSButton}