UISlider to adjust to match UITextField Value - ios

I have a textfield on a form where the value changes based on the slider. I am trying update the functionality so that when the user enters a value in the text field the slider will move to the correct position. My UISlider will be a value between 0 and 3.
I have been trying to use this post to help me but, I have not been able to get it to work: How to set value of UISlider from a UITextField
Cheers,
I want the user to be able to use the slider or keyboard to enter the rate discount - but if they enter a value I want the slider to move to the right spot. Using the code given the app crashes. I think it's because of conflicting code. I have been linking the sider as an outlet. Is this correct?

Are you failing because yoru link is an Objective C version? So here is the swift equivalent. First, add a listener on your textfield like this
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
Then in your text field text change function, set value for your slider
func textFieldDidChange(textField: UITextField) {
if let stringValue = textField.text{
if let intValue = Int(stringValue){
slider.setValue(intValue, animated: true)
}
}
}

Related

Check if a date was picked via textfield and date picker

I have 2 text fields in my storyboard. One for username, the other one to pick a date. However, I am trying to validate the if the user has a specific amount of characters in the username:
func addTargetToTextField() {
registerUserNameText.addTarget(self, action: #selector(textFieldDidChange), for: UIControl.Event.editingChanged)
}
and
#objc func textFieldDidChange() {
let isText = registerUserNameText.text?.count ?? 0 > 3
if isText { ... etc
I am trying to copy that methods on my date picker text field, but it is not working. Im not a Swift expert, but I think it is because the user picks a date and not writing something in the textfield.
How can I check if a date in the textfield was picked?
I changed the addTarget method of my DatePicker and not the TextField using .valueChanged and it is working now.

How to disable UIControlEventEditingChanged

I have a UIViewController with several UITextFields. When tap one text field, it should present the barcode scanning view controller. Once the scanning is completed, my barcode scanning viewcontroller is disappearing (used "dismissViewcontroller") and the scanned value should entered into the text field I tapped. This is working fine. I have set the delegate for each text field like this.
[field addTarget:metrixUIViewControllerIn action:#selector(executeScriptOnTextFieldChange:) forControlEvents:UIControlEventEditingChanged];
The problem is this :
Lets say I have set an alert to display inside this executeScriptOnTextFieldChange method. Once I tapped on the 1st text field, then the barcode scanner comes. Once I scanned barcode scanner closes and set the value for the first text field and fire the alert.Thats ok. But then if scanned by tapping the 2nd textfield and the string will set to that textfield and fire the alert related to 2nd textfield also fire the alert related to first textfield as well. I want to stop happening this. Is there any way to disable the delegate for one textfield? This happens because I am refreshing the view in the viewDidAppear. But I have to do that as well. Please help me.
UIControlEventEditingChanged for a textField can fire at many different events that are not even directly related to that textField, but related inderectly.
For instance, when your ViewController is presenting the barcodeScanner it may trigger a "resignFirstResponder" event on the textField. Also when the 2nd textField is tapped, cause the 2nd becomes first responder and the 1st suffers a "resignFirstResponder".
I suggest trying to use a UITapGestureRecognizer in your textField instead. Example:
Swift 4
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.textField.tag = 1
self.textField.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(fireTextField(_:))))
}
#objc func fireTextField(_ sender: UIGestureRecognizer){
let view = sender.view
guard view != nil else{
//Do nothing
return
}
let condition = view!.tag == 1
if condition{
//or do whatever other stuff you need
self.textField.becomeFirstResponder()
}else{
//Whatever for other textFields
}
}
This way, you could use the "tag" attribute to determine which textField is firing and so adjust "condition". You could also filter the flow with a switch using the "tag".
Not sure if any of this will really help as I would need more info about the flow you need to accomplish. Hope it does help!

iOS: Good way to pass value from image button to func in the class

Initially I had two buttons with titles: "+" and "-". Both buttons are located in table cell. I have used protocol and delegate to pass value from button title to function call which depends on input params. If input parameter is "-" - decrease value, if "+" - increase.
But later I removed titles and replaced buttons with respective images. And here I faced an issue - I cannot call function properly because title is blank.
I have implemented the following workaround. I have set Accessibility Identifier for both buttons. For example for +:
And in cell class I used accessibilityIdentifier:
#IBAction func didPressOrderCellButton(_ sender: UIButton) {
cellDelegate?.didPressOrderCellButton(order: order!, menuItem: menuItem!, action: sender.accessibilityIdentifier!)
}
But... I have some doubts if it's proper way to do this. Will it create any issues in future if I decide to work with accessibility feature?
I do not want to use title and add code to ViewController class to hide it every time view is loaded or appeared. I want to avoid such solutions in my code because it's too difficult to support such solutions I believe.
I have tried to find another button identifier that I can use, but didn't succeed.
The simple approach would be just set the tag value inside your button and then check the same tag value and perform your operation Plus or Minus accordingly.
For instance:-
if sender.tag == 0 {
//Do minus
} else if sender.tag == 1 {
//Do plus
}

Swift 2: Call a method after pressing Return in UITextField

I have a Text Field in a Tip Calculator. I want the Tip Calculator to update all the fields of my calculator.
With the current code that I have now, for whatever reason. It doesn't call calcTip() (or atleast it doesn't seem to) until I press return once, enter another (or the same) value and press return again.
I'm really close to having this app work exactly how I want it to, and I feel like I'm just 1 or 2 lines away.
My ViewController conforms to UITextFieldDelegate, and I declared amountBeforeTaxTextField.delegate = self in viewDidLoad.
TextShouldReturn:
func textFieldShouldReturn(textField: UITextField) -> Bool {
amountBeforeTaxTextField.clearsOnBeginEditing = true
amountBeforeTaxTextField.becomeFirstResponder()
calcTip()
amountBeforeTaxTextField.resignFirstResponder()
return true
}
calcTip():
func calcTip() {
let tip = tipCalc.calculateTip()
let total = tipCalc.calculateTotal()
let tax = tipCalc.calculateTax()
let perPerson = total / Float(Int(partySizeSlider.value))
tipCalc.tipPercentage = (tipPercentageSlider.value)
tipCalc.amountBeforeTax = (amountBeforeTaxTextField.text! as
NSString).floatValue
tipCalc.taxPercentage = (taxPercentageSlider.value)
resultLabel.text = String(format: "Tip $%.2f, Tax: $%.2f Total: $%.2f", tip, tax, total)
perPersonLabel.text = String(format: "Per-Person Total: $%.2f", perPerson)
}
Note: I have the same outcome with & without .becomeFirstResponder()
Thanks for reading.
So your textFieldShouldReturn function is called when you press the bottom right button on the keyboard, which can have various titles; such as "Go", "Return", "Done", or "Send".
Your first line, only accomplishes a UI effect; meaning when the user taps on the textfield to input text, there will be a little box that appears on the far right handside of the textfield that allows the user to clear the inputted text, if there is any. Sort of like a reset.
When you use becomeFirstResponder, you are pretty much calling another keyboard to pop up, so you aren't accomplishing anything by doing that.
When you use resignFirstResponder, you are hiding the keyboard.
What you want to do is remove "becomeFirstResponder" as well as the first line, because those don't do anything to help your problem. That should be the solution to the problem you are facing.

Touch Up Inside not working properly

I have an app with some buttons, when those buttons are pressed the image on them should change. I assume that the TouchUpInside runs when you tap and remove the finger while still holding inside the area of the element, however it only works rarely and I'm not sure why.
The reason I use TouchUpInside instead of TouchDown is because I want the user to be able to cancel the action.
I'm sorry if I've misunderstood anything about those events and if this has already been asked. I couldn't find an answer to my problem searching the web.
//The IBAction is set to trigger on TouchUpInside
#IBAction func action11(sender: UIButton) {
setTile(sender)
}
func setTile(sender: UIButton) {
if turn {
print("O's turn")
sender.setImage(xTile, forState: .Normal)
turn = false
}
}
EDIT: Added the necessary code
There are some properties of UIButtons which you can use to achieve what you want.
You can use Default and selected state of uibutton to set two different images.
In XIB select state "Default" and assign default image to that state again select state to "Selected" and assign image which you want after button section.
and add following line in button selection method.
-(IBAction)buttonTapped:(UIButton *)sender{
sender.selected = !sender.selected;
}
Your understanding is correct, you need to use touchUpInside.
I assume you are trying to create a button that has a toggle function. On one touch you want the button to have the value Say "X" and when touched again the button has a value "O".
Take a look at this code below, this should do the job.
class ViewController: UIViewController {
var isButtonPressed = false{
// Adding a Property Observer, that reacts to changes in button state
didSet{
if isButtonPressed{
// Set the Value to X.
}else{
// Set the Value to O.
}
}
}
#IBAction func changeButtonValue(sender: UIButton) {
// Toggle the button value.
isButtonPressed = !isButtonPressed
}
}
If you don't set turn=true after the first time, this code is executed it will be executed only one.
if turn {
print("O's turn")
sender.setImage(xTile, forState: .Normal)
turn = false
}
Check if the button frame is large enough to get finger touch.
Apple says at least 35x35 pixel.

Resources