2015-08-17 3 views
0

Я хочу, чтобы все текстовые поля реагировали в реальном времени, я хочу, чтобы все они захватили символы, которые были напечатаны и что-то сделали, но, похоже, я не могу заставить два утверждения действовать в гармонии внутри метода textField:shouldChangeCharactersInRange. вот код, который я пытаюсь выполнить:несколько операторов внутри textField: shouldChangeCharactersInRange метод?

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 

     let invalidCharacters = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_").invertedSet 

     if textField == usernameTxt || textField == passwordTxt || textField == confirmTxt { 

      if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex)) { 

       println("error") 

       return false 
      } 
      return true 

     }; if range.length + range.location > count(usernameTxt.text) { 


      return false 

     }else { 

     let NewLength = count(usernameTxt.text) + count(string) - range.length 

     return NewLength <= 5 

     } 
    return true 
    } 

первое утверждение кода работает, когда он один в FUNC, однако, когда я пытаюсь добавить второе заявление, я получаю следующее сообщение об ошибке:

enter image description here

почему так? и как я должен достичь этого правильно?

и у меня есть этот последний метод для реализации в функции, которая будет проверять в режиме реального времени, если имя пользователя уже принято:

var isTaken: Bool = false 

     var query = PFQuery(className: "_User") 
     query.whereKey("username", equalTo: usernameTxt.text) 
     query.findObjectsInBackgroundWithBlock { 
      (objects: [AnyObject]?, error: NSError?) in 
      if error == nil { 
       if (objects!.count > 0){ 
        isTaken = true 
        let myAlert = SCLAlertView().showError("Woah There", subTitle: "username \(textField.text) is already taken", closeButtonTitle: "Got It") 
        myAlert.alertview.contentView.backgroundColor = UIColor(red:1.0, green:0.18, blue:0.18, alpha:1.0) 
        myAlert.alertview.circleBG.backgroundColor = UIColor(red:1.0, green:0.18, blue:0.18, alpha:1.0) 
        myAlert.alertview.labelTitle.textColor = UIColor.whiteColor() 
        myAlert.alertview.contentView.layer.borderColor = UIColor(red:1.0, green:0.18, blue:0.18, alpha:1.0).CGColor 
        myAlert.alertview.viewText.textColor = UIColor.whiteColor() 
        myAlert.alertview.viewText.backgroundColor = UIColor(red:1.0, green:0.18, blue:0.18, alpha:1.0) 

       } else { 
        println("Username is available. ") 
       } 
      } else { 
       println("error") 
      } 
     } 
+0

Что происходит, когда вы удаляете второй «возврат истины», который находится прямо посреди вашего метода? Seemis, похоже, возможно, это отрезает метод до того, как у него есть время, чтобы перейти ко второму, если/then заявление, возможно, вернет false } return true }; если range.length + range.location> count (usernameTxt.text) {this return true statment, а не нижний – Loxx

+0

, когда я отделяю средние возвращаемые истинные утверждения, он не имеет никакого эффекта для последнего, вероятно, потому, что средний возврат истинного оператора привязывается только к первому утверждению, а не ко всей функции. –

+0

О да, nvm, я вижу, что вы делаете, одна секунда – Loxx

ответ

2

Таким образом, это должно работать, реорганизованы, чтобы захватить то, что мы говорили о том, в комментариях выше:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    let invalidCharacters = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_").invertedSet 

    if textField == usernameTxt || textField == passwordTxt || textField == confirmTxt { 
     if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex)) { 
      println("error") 
      return false 
     } 
     if textField == usernameTxt { 
      if range.length + range.location > count(usernameTxt.text) { 
       return false 
      } else { 
       let NewLength = count(usernameTxt.text) + count(string) - range.length 
       return NewLength <= 5 
      } 
     } 
     return true 
    } 
    return false 
} 

Это начало, но мы будем продолжать работать над этим, однако, это должно захватить заявление возвращения в правильном порядке, учитывая то, что вы хотите. Первое, если/затем отфильтрует поле электронной почты и вернет false, второе, если/then вернет false, если оно истинно, тогда мы проверим только имя пользователя, мы работаем в поле имени пользователя и возвращаем true или false в поле имени пользователя, если THIS не является полем пользователя, мы возвращаем true.

Теперь, что касается части имени пользователя, что вы пытаетесь выполнить там, просто укажите это, я не хочу продумать эту логику, как только я это узнаю, тогда мы сможем решить любые проблемы с именем пользователя - конкретное утверждение if/then, в чем цель? И, что имеет приоритет для поля имени пользователя, является ли проверка символа для поля имени пользователя приоритетом или является ли это следующей проверкой имени пользователя? Я прошу, потому что этот метод завершится, если поле имени пользователя TRUE для второго if/then оператора этой функции, и оно никогда не достигнет второй, если/then функция для имени пользователя.

Вторая часть вашего вопроса, возможно, лучший способ сделать это, так как пользователь, функция делегата из UITextFieldDelegate для перехвата «RETURN KEY», нажимает на пользователя, когда они пытаются перейти к следующему полю, это будет перехватить это событие и проверить, чтобы убедиться, что имя пользователя не принимается:

func textFieldShouldReturn(textField: UITextField!) -> Bool{ 
    if (textField === usernameTxt) { 
     var isTaken: Bool = false 
     var query = PFQuery(className: "_User") 
     query.whereKey("username", equalTo: usernameTxt.text) 
     query.findObjectsInBackgroundWithBlock { 
      (objects: [AnyObject]?, error: NSError?) in 
      if error == nil { 
       if (objects!.count > 0){ 
        isTaken = true 
        let myAlert = SCLAlertView().showError("Woah There", subTitle: "username \(textField.text) is already taken", closeButtonTitle: "Got It") 
        myAlert.alertview.contentView.backgroundColor = UIColor(red:1.0, green:0.18, blue:0.18, alpha:1.0) 
        myAlert.alertview.circleBG.backgroundColor = UIColor(red:1.0, green:0.18, blue:0.18, alpha:1.0) 
        myAlert.alertview.labelTitle.textColor = UIColor.whiteColor() 
        myAlert.alertview.contentView.layer.borderColor = UIColor(red:1.0, green:0.18, blue:0.18, alpha:1.0).CGColor 
        myAlert.alertview.viewText.textColor = UIColor.whiteColor() 
        myAlert.alertview.viewText.backgroundColor = UIColor(red:1.0, green:0.18, blue:0.18, alpha:1.0) 
       } else { 
        println("Username is available. ") 
       } 
      } else { 
       println("error") 
      } 
     } 
    } 
    return true 
} 

Вот ответ на ваш последний вопрос, а это должно быть ответ, это, чтобы убедиться, что вы попав в поле имя пользователя в два раза до возвращения функции:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    if textField == emailTxt { 
     return true 
    } else { 
     let invalidCharacters = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_").invertedSet 
     let range2 = range 
     if textField == usernameTxt || textField == passwordTxt || textField == confirmTxt { 
      if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex)) { 
       println("error") 
       if textField == usernameTxt { 
        if range2.length + range2.location > count(usernameTxt.text) { 
         return false 
        } else { 
         let NewLength = count(usernameTxt.text) + count(string) - range2.length 
         return NewLength <= 5 
        } 
       } 
       return false 
      } 
      if textField == usernameTxt { 
       if range.length + range.location > count(usernameTxt.text) { 
        return false 
       } else { 
        let NewLength = count(usernameTxt.text) + count(string) - range.length 
        return NewLength <= 5 
       } 
      } 
      return true 
     } 
     return false 
    } 
} 

Вы видите, первый, если/затем захватывает нужные поля, второй, если/затем захватывает те, у которых есть плохие шакаторы, третий фиксирует поле имени пользователя и RETURNS, если оно истинно или ложно, так что это проблема с первым решение, которое я разместил выше этого, вам нужно будет дважды проверять длину имени пользователя в этом методе, а поле имени пользователя будет проверяться только один раз в этой функции. Итак, я дублирую проверку IF/THEN на длину текста имени пользователя, но это нормально, она должна работать в любом случае. Это было бы BEST, если бы у вас был другой «BOOL return FUNCTION», который был вне этого метода, который проверял длину имени пользователя, а затем возвращал true или false, но это тоже будет работать с дублированием кода в 1, если/then-инструкция.

+0

да это прекрасно! он работал так, как я хотел –

+0

сейчас, когда мы на тему, у меня есть еще один запрос, я хочу добавить еще один оператор/метод, который будет проверять, было ли введено имя пользователя в текстовое поле 'usernameTxt', проверьте обновленные вопрос –

+0

уверен, k, одна секунда, о очень хорошо, я люблю парсы, позвольте мне взглянуть на это очень быстро – Loxx

Смежные вопросы