I can't change the text of a UILabel in Swift - swift

I am trying to change the text of a UILabel in my code, but the text won't change.
I tried to use the well-known command for changing the text, "NameOfLabel.text = 'Hello", but that did not work. So I tried to put it in a start function so you would click a UIButton and it would change the text, didn't work either.
#IBOutlet var nameOfRobot: UILabel!
#IBAction func startButton(_ sender: Any){
let nameNumber = Int.random(in: 1...3)
if nameNumber == 1 {
self.nameOfRobot.text = "Ben"
}
if nameNumber == 2 {
self.nameOfRobot.text = "Oliver"
}
if nameNumber == 3 {
self.nameOfRobot.text = "Colton"
}
}
I want it to choose a number between 1 and three and have it change the UILabel to that name. When I start the app though, it works, but it doesn't change the text of the label.

Looks like you forgot to connect the action to the button press:
You can tell this is done correctly by looking at the full circle indicator in the editor:
EDIT: Setting the correct class to the viewController in the storyboard:

Related

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!

copying label text to clipboard when clicked [duplicate]

This question already has answers here:
How to make a UILabel clickable?
(12 answers)
Closed 3 years ago.
first I have to make UILabel clickable and when it clicked it should copy its text to clipboard. I am using Xcode 10 with swift 5.1.
so firstly I am expecting label to be clickable and after that, this click action copy its text to clipboard. this is a basic level program.
To make the label "clickable" :
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(labelDidGetTapped:))
yourLabel.userInteractionEnabled = true
yourLabel.addGestureRecognizer(tapGesture)
Then, to retrieve the text from the label and copy it to the clipboard :
#objc
func labelDidGetTapped(sender: UITapGestureRecognizer) {
guard let label = sender.view as? UILabel else {
return
}
UIPasteboard.general.string = label.text
}
Note that there won't be any effect when tapping the text, it would be best to present some kind of feedback to the user, by animating the label's alpha for example
Part one of the answer can be followed as -
#IBOutlet weak var clickAble: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// this code is for making label clickable.
clickAble.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapFunction))
tap.numberOfTapsRequired = 1
clickAble.addGestureRecognizer(tap)
}
Part 2nd of answer is as-
#objc func tapFunction(sender:UITapGestureRecognizer)
{
// this is for copying label text to clipboard.
let labeltext = clickAble.text
UIPasteboard.general.string = labeltext
}
}
Try making user interaction enabled. For example:
yourLabel.isUserInteractionEnabled = true
Check this previous thread. This question has already been answered.
How to make a UILabel clickable?
For copying text to your clipBoard.
UIPasteboard.general.string = yourLabel.text

Scroll to end of UITextView when text contains returns

I am using Swift and have a UITextView that I wish to always keep scrolling as I add new text and the length of the text is greater than what the textView can display.
The following works perfectly as long as my textview does not contain any new lines "\n"
let range = NSMakeRange(textView.text.count - 1, 1)
textView.scrollRangeToVisible(range)
However, as soon as I add a return, the range no longer is valid for the scroll.
I have checked out as many of the related posts as I can, but none seem to address this problem. Can anyone help?
OK. I discovered what the issue was. if a UITextView is made unselectable, when you programatically add text to the view, the view will not scroll properly if there are returns in the text, whereas text without returns scrolled perfectly.
Here is a simple example. Create a Viewcontroller with one button and a UITextView.
Wire it up and play with the two Bools.
You will find that if isSelectable = false and isReturnText = true then it will not scroll, however if isReturnText = false, it scrolls find.
If I set isSelectable = true then both scroll perfectly as expected.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var textView: UITextView!
var isSelectable:Bool = true
var isReturnText:Bool = true
let returnText = "These sentences are separated by returns.\n"
let nonReturnText = "These sentences are separated by space. "
override func viewDidLoad() {
super.viewDidLoad()
textView.isSelectable = isSelectable
}
#IBAction func addNoReturnText(_ sender: Any) {
textView.text += isReturnText ? returnText : nonReturnText
let range = NSMakeRange(textView.text.count - 1, 1)
textView.scrollRangeToVisible(range)
}
}

Can I change outlets using an array, instead of hard coding everything?

I have an app where a user can select a number of different buttons onscreen. When a user selects a button, it turns green and the text will be used in a later view. I am trying to make everything nice and swift by minimising the amount of code I am writing.
Every button is connected to the same action and their identity is determined by their tag. What I have done is created 2 arrays to track the card name and their on/off state. When a card is pressed the cardPressed function is called, this decides whether to turn the card green or white currently (it will do more later).
What I want to do is to perform the colour change in one line of code, instead of
cardOne.backgroundColor = UIColor.white
I want to do this [#1]
cardList[cardNumber].backgroundColor = UIColor.green
so that my outlet changes depending on the selection made. I would normally just have a massive switch statement that would read like so
switch cardList[cardNumber] {
case 0:
cardOne.backgroundColor = UIColor.green
case 1:
cardTwo.backgroundColor = UIColor.green
case 2:
cardThree.backgroundColor = UIColor.green
case So on so forth:
cardInfinity.......
default:
break
}
Obviously when I try to do [#1] I get an error because it is a string, not an outlet connection. What I would like to know, is there anyway to trick xcode into recognising it as an outlet, or better yet have a way to change the outlets I am acting upon in one line of code?
Hopefully I haven't rambled too much and you can understand my thought process! I have included all of the relevant code below, obviously it won't compile. If you have any ideas they would be appreciated, or if I'm being too optimistic and this isnt possible, just let me know :) for now I will be using a big switch statement! (maybe this is useful to me in the future!)
Thanks!
private let cardList = ["cardOne","cardTwo","cardThree"]
private var cardState = [false, false, false]
//Card functions
private func selectCard(cardNumber: Int){
cardState[cardNumber] = true
cardList[cardNumber].backgroundColor = UIColor.green
}
private func deselectCard(cardNumber: Int){
cardState[cardNumber] = false
//cardOne.backgroundColor = UIColor.white
}
//Decide which function to perform, based on the card information recieved
private func cardPressed(cardNumber: Int){
let selectedCardName = cardList[cardNumber]
let selectedCardState = cardState[cardNumber]
print("\(selectedCardName)")
print("\(selectedCardState)")
switch selectedCardState {
case true:
deselectCard(cardNumber: cardNumber)
case false:
selectCard(cardNumber: cardNumber)
}
}
//UI Connections
//Card button actions
#IBAction func buttonPressed(_ sender: UIButton) {
//Determine which button has been pressed
//let cardName = sender.currentTitle!
let cardSelection = sender.tag - 1
cardPressed(cardNumber: cardSelection)
}
//Card button outlets
#IBOutlet weak var cardOne: UIButton!
#IBOutlet weak var cardTwo: UIButton!
The solution lies in the wonderful world of object-oriented programming. Instead of using parallel arrays, you can create your own data type to group this data and behavior together.
If you created your own UIButton subclass, you could keep track of whether the button is selected with your own custom property, and make visual modifications as needed.
class CardButton: UIButton {
var isChosen: Bool = false {
didSet { backgroundColor = isChosen ? UIColor.green : UIColor.white }
}
}
If you set the buttons in the storyboard to be your new CardButton type, you can use their isChosen property in code.
Your buttonPressed function could look like this instead:
#IBAction func buttonPressed(_ sender: CardButton) {
sender.isChosen = !sender.isChosen
}
This would allow you to remove the majority of your existing code, since the data is stored inside each of your buttons.

(swift) Anyone can help me to make bulk change to those buttons?

here is the screenshot
when user get into this page, I want to change the background of those button.
for example, when the level of user is 6, I want to change the top 6 background of buttons to a blue picture as first button. I don't wanna write a code one by one, so please help me to write a function, Thank you very much!
You can add you buttons to the array in order of increasing level and do something like this:
var buttons: [UIButton] // array of your buttons, next you need to init it
...
func setColorForUserLevel(userLevel: Int) {
if userLevel > buttons.count {
return
} else {
for i in 0...userLevel - 1 {
buttons[i].backgroundColor = UIColor.blueColor()
}
}
}
I create simple example project to show how to use it:
I have outlets with UIButton! type and buttons object in code:
And i test setColorForUserLevel function in viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
buttons = [button1, button2, button3]
setColorForUserLevel(2)
}