1
votes

I'm using Xcode 8 and Swift 3.

I have a project with 3 textfields, 1 button to clear and label to display result.

Inside my class ViewController I have:

class ViewController: UIViewController,UITextFieldDelegate {

@IBOutlet weak var input1: UITextField!
@IBOutlet weak var input2: UITextField!
@IBOutlet weak var input3: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBOutlet weak var clearButton: UIButton!

I want to limit my textfields inputs to max 3 digits but also to a value of 360. I manage to get code for both things and they work if used only one at a time but because they both start with func textfield I can't make them both work together. Do I have to do it in different class? I know this is a basic question but its part of the learning process.

These are the two codes I want to combine:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, 
               replacementString string: String) -> Bool
{
    let maxLength = 3
    let currentString: NSString = textField.text! as NSString
    let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
    return newString.length <= maxLength
}

and:

func textField(_ textField: UITextField,
               shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool
{
    var startString = ""
    if (textField.text != nil)
    {
        startString += textField.text!
    }
    startString += string
    let limitNumber = Int(startString)
    if limitNumber! > 360
    {
        return false
    }
    else
    {
        return true;
    }
}

They are both inside the class ViewController.

Thanks for the help!

4
For this scenario, I don't think you need to identify which textfield is which. All the variables inside these functions are local. These are functions of UITextFieldDelegate. Are you setting them to self for all UITextFields? - KrishnaCA

4 Answers

1
votes

If I am not mistaken, here is all you need:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, 
               replacementString string: String) -> Bool {
    let maxLength = 3
    let limitValue = 360

    let text = textField.text!
    let currentString: NSString = text as NSString
    let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString

   var startString = ""

    if !text.isEmpty {
        startString += text
    }
    startString += string

    let limitNumber = Int(startString)!

    return limitNumber < limitValue && newString.length <= maxLength
}

Update:

Auto focus on a next texfield.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, 
                   replacementString string: String) -> Bool {
    let maxLength = 3
    let limitValue = 360

    let text = textField.text!
    let currentString: NSString = text as NSString
    let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString

   var startString = ""

    if !text.isEmpty {
        startString += text
    }
    startString += string

    let limitNumber = Int(startString)!

    let newLength: Int = newString.length

    if textField == input1 {
        if newLength == maxLength {
            input2.becomeFirstResponder()
        }
    }
    if textField == input2 {
        if newLength == maxLength {
            input3.becomeFirstResponder()
        }
    }

    if textField == input3 {
        if newLength ==  maxLength {
           self.view.endEditing(true)
        }
    }

    return limitNumber < limitValue && newLength <= maxLength
}
1
votes

You need to add an if statement in func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool checking for the current textFieldlike this:

func textField(_ textField: UITextField,  shouldChangeCharactersIn range: NSRange,  replacementString string: String) -> Bool {
   if textFiled == input1 {
   // do logic for input1
   } else if textFiled == input2 {
   // do logic for input2
   }
}
1
votes

Swift switch statement will do it.

func textField(_ textField: UITextField,
               shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool
{
    switch textField {
    case input1:
        // ...
    case input2:
        // ...
    case input3:
        // ...
    default:
        break
    }
}
0
votes

People didn't understood the question. Actually, all you need is merging your statement as mentioned by javimuu.

My answer is terrible since javimuu's one is correct but I'm writing it because I don't have enough rep to down vote those people who up votes each other in an useless way.

  func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool
{
    let maxLength = 3
    let currentString: NSString = textField.text! as NSString
    let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString

    var startString = ""
    if (textField.text != nil)
    {
        startString += textField.text!
    }
    startString += string
    let limitNumber = Int(startString)


    return newString.length <= maxLength && limitNumber! <= 360
}