So I have 4 textfields with lines underneath them all. When the user enters a number into the first textfield it jumps to the next and so on until a number it entered into the last field at that point the keyboard will just resign and the pin will be evaluated. I want to be able to change the color of the lines depending on which textfield is focused the time.
What I have tried
So far I've tried making an instance of an observable object in a representable swift file that makes up my textfield. So I'll change the Observable Object when nextField becomes first responder and I'll change a state variable in my SwiftUI file. When I try to make an instance of my Observable Object in my representable file I get an error that states "Class 'SchoolCode_WrappableTextField' has no initializers". Overall I'm essentially just trying to change the color of the underline depending on which textfield is focused at the time. Any help is appreciated, thanks.
#objc func textChanged(sender: UITextField) {
if (sender.text?.count)! > 0 {
if let nextField = sender.superview?.superview?.viewWithTag(sender.tag + 1) as? UITextField{
nextField.becomeFirstResponder()
}else{
sender.resignFirstResponder()
}
}
}`
UI
Related
I'm writing an application which has an NSSplitViewController as the main View-Controller. I have it linked-up so that clicking a button in the menubar will trigger an #IBAction which then calls a function in one of the sub-View-Controllers.
if let board = storyboard {
let imageController = board.instantiateController(withIdentifier: "VC_image_ID") as! VC_image
imageController.viewDidAppear() // necessary or else I'll get an "Unexpectedly found nil" later on
DispatchQueue.global().async{imageController.processImage(path)} // path variable was set earlier in the code, but not shown here
}
Inside the sub-View-Controller (named VC_image), I'm trying to change the stringValue of a label by using the following code:
public func processImage(_ path: String) {
DispatchQueue.main.async {
self.imageText.stringValue = path
print(self.imageText.stringValue)
}
}
Although the imageText.stringValue actually seems to have changed based on the fact that it prints the updated text (through the console), the text in the window never changes. Why is this happening? The reason is probably really obvious to professionals, but I'm still an amateur and can't figure it out. Thanks.
I have created an app with a codeable array in Swift. I have a boolean field to show which item in my list is the active record. If I choose another item in my list to make active (true) I would like to mark all other records as false. I was wondering if using a for-in loop would be the proper way to do this?
I have this code to activate the button but have been told that is not the proper way to do it.
#IBAction func activateButtonTapped(_ sender: UIButton) {
activateButton.isSelected = !activateButton.isSelected
updateSaveButtonState()
}
Any suggestions would be appreciated.
A for-loop would be the most naive (simple) way to do this, but not the most performant as the number of button increases (you're bound by O(n) time).
If one and only one button can be active at a time then you're better off using another variable to reference the currently active button. Your code would instead look like this:
private weak var activeButton: UIButton?
#IBAction func activateButtonTapped(_ sender: UIButton) {
activeButton?.isSelected = false
sender.isSelected = true
activeButton = sender
}
This ensures O(1) time.
If you want multiple buttons active at once, you can use an array of active buttons, which you'd loop over to deactivate. In that case, you still have a worst case O(n) time complexity, but you're almost always going to be looping over a smaller subset of the buttons.
Yes, a for in loop would be perfect for this. You could set all the buttons selection status to false and then set the one you just activated to true.
for button in buttons {
button.isSelected = false
}
activateButton.isSelected = true
Or you could check in the loop if the button being tapped is the one that in the loop.
for button in buttons {
button.isSelected = button == activateButton
}
Heys guys,
I am pretty new into programming and therefore I've followed I course on Udemy to teach me Swift 2.2.
For learning purpose I have been trying to program a BMI-calculator where I have a textfield (which just displays the value) and a slider where I can put my weight in kg. After dragging the slider the value is visible in the textfield. I cannot put a value into the textfield so that it is displayed on the slider!
The same textfield-slider relation is used with the height in cm. Now I created an IBAction the bring my kgSlider.value into my kgField.text and it looks like this:
#IBAction func kgSet(sender: AnyObject) {
kgField.text! = String(Int(kgSlider.value))
}
Thats works fine but I unwrapped (like the teacher in the course) without knowing, if there really is a value. Okay, I know in this case that there will be a value, but I would like to go more real and therefore I tried to use an Optional-Binding to find out, if there is a value instead of directly unwrap it.
Therefore I used the cm.Field and the cm.Slider in my code but it doesn't work for now and I don't know why. The code is the following:
#IBAction func cmSet(sender: AnyObject) {
if let tempCm = String(Int(cmSlider.value)) as String! {
cmField.text = tempCm
}
}
So I created the constant called tempCM which will got the value from the cmSlider, if there is a value. Therefore I casted the cmSlider.value like in the other IBAction into an Int and then into a String. If there is the value it will carry it into the cmField.text. This didn't work, therefore I tried to use the "as String!" statement but know I get always 0 instead of the correct value.
So what am I doing wrong there?
So, this should compile fine and provide you with your desired result.
#IBAction func cmSet(sender: AnyObject) {
if let tempCm = String(Int(cmSlider.value)) {
cmField.text = tempCm
}
}
You could also try this
cmField.text = String(Int(cmSlider.value)) ?? " "
in the second example, you are using the optional operator to say if you can convert this to an Int then that Int to a string set the cmField.text property to its value, otherwise use a blank space as the default value.
In my app I have got two textfields, one label and one button. I managed to get the content of the one textfield to be displayed in the label, but I want to display the content of both of the textfields.
#IBAction func buttonPushed(sender: UIButton) {
Label.text = "\(textfield1.text)"
+ "\(textfield2.text)"
The code above is the closest I´ve come, but the Label displays:
Optional"whatever I typed in the textfield"Optional"whatever I typed
in the textfield"
You have to unwrap the text
Label.text = textfield1.text! + textfield2.text!
You are concatenating strings, not adding numbers. In order to add the values, you need to cast the textfield value to a number like:
field.text!.toInt()
the ! unwraps the value to remove the "Optional". and toInt() casts a string (text) to and integer.
In the end, you code will look something like this:
#IBAction func buttonPushed(sender: UIButton) {
Label.text = "\(textfield1.text!.toInt())"
+ "\(textfield2.text!.toInt())"
I want to get the length of the text that is entered in a UISearchBar
I use the function that is called when the the searcbbar text starts editing.
func searchBarTextDidBeginEditing(searchBar: UISearchBar!) {
println("EDITING")
//TODO: Get length of text entered in searchBar
}
This doesn't work:
func searchBarTextDidBeginEditing(searchBar: UISearchBar!) {
println("EDITING")
//TODO: Get length of text entered in searchBar
//Doesn't work. Error: String doesn't have a member named length
searchBar.text.length
}
How can i retrieve the length of the entered text?
Ended up doing this:
searchBar.text.bridgeToObjectiveC().length
The problem is simply that the text property, like most objects arriving from the Cocoa API, might be nil. You have to assure Swift that it is not. Like this:
let len = countElements(searchBar.text!)