2015-04-10 5 views
2

Я пытаюсь понять эту строку, которая очень хорошо работает для backspace после того, как я ограничу пользователя до 24 символов. Но я не знаю, как это работает.Зачем изменять значение range.length для backspace в ifChangeCharactersInRange delegate methos?

Я попытался вычислить значение range.length, и он установлен в 0, если я вставляю некоторые символы. Но я получаю значение, установленное в 1, когда я нажимаю кнопку «Назад» при удалении символов? Почему это?

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

    println("range is \(range)") 
    println("range location is \(range.location)") 
    println("range length is \(range.length)")  

    if (textlength - (range.length) + count(string)) > 24 {     
     textField.layer.borderColor = UIColor.redColor().CGColor 
     textField.layer.borderWidth = 1.0 

     println("\(newString)") 
     return false 
    }   
    return true 
} 

ответ

4

Попробуйте ввести текст длиной 3 символа. Затем выберите все и нажмите cut. Вы должны увидеть что-то вроде:

range is (0,3) 
range location is 0 
range length is 3 

При вставке вы получите длину 0, так как ничего не выбрано. У вас только есть курсор. Когда вы удаляете свой диапазон, длина будет длиной строки, которую можно удалить. Когда вы ударяете назад, вы просто удаляете последний символ, поэтому range.length равен 1.

+0

Кстати, из вашего кода не ясно, где '' textlength' и newString' пришли. В любом случае надеюсь, что мой намек поможет. –

+0

umm..thanks действительно умное тестирование .... еще один вопрос ... let modified = current.stringByReplacingCharactersInRange (range, withString: string) .. Если да, то как эта линия работает ... перед заменой charactes он выбирает всю длину, а затем добавляет новую строку ...или это значение диапазона, установленное равным 0 во время этого утверждения, тоже –

+2

, возможно, вы ссылаетесь на пример @DarkDust. В любом случае «диапазон», передаваемый 'shouldChange ...', является положением и длиной того, что _shouldChange_. Остерегайтесь не путать его с длиной замены. В качестве другого примера вы можете попробовать выбрать 3 символа, а затем нажать букву (вместо спины). На этот раз пройденный диапазон будет иметь длину 3 (поскольку 3 символа будут заменены), а строка замены будет единственным символом. 'modified ...' заменит выбранные 3 символа (в' range' from 'current') единственным символом' replacementString' –

1

Возможно, самый простой способ выполнить эту проверку длины - это применить замену, а затем проверить строку результата.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    let current = textField.text 
    let modified = current.stringByReplacingCharactersInRange(range, withString: string) 

    if (modified.length > 24 {     
     textField.layer.borderColor = UIColor.redColor().CGColor 
     textField.layer.borderWidth = 1.0 

     println("\(modified)") 
     return false 
    }   
    return true 
} 
+0

wow! Спасибо .. очень просто :) –

2

Метод говорит shouldChangeCharacterInRange, поэтому, когда вы вставляете новый символ, не существующие символы не должны быть заменены или удалены, поэтому он дает вам длину, как и 0. Принимая во внимание, когда вы удалите символ, он будет возвращать вы диапазон характера будут удалены, и это, очевидно, будет 1.

Ex:

Допустим, у вас есть текст Hello World Это 11 символов.

Теперь, когда вы вставляете новый символ !, он вернет вам диапазон после последнего символа, в который будет вставлен этот новый символ, то есть {11,0}.

Теперь, когда вы удаляете символ, скажем, последний символ, он вернет вам диапазон для этого последнего символа, то есть {10,1}.

Вы можете проверить это, долго нажимая некоторый текст и удаляя его. Допустим, если вы долго нажимаете «World» и удаляете его. Это вернет вам диапазон с длиной 5, т.е. {5,5}.


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

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

    let stringAfterAppendingChanges = textField.text.stringByReplacingCharactersInRange(range, withString: string) 

    if (stringAfterAppendingChanges.length > 24 {     
     textField.layer.borderColor = UIColor.redColor().CGColor 
     textField.layer.borderWidth = 1.0 

     println("\(stringAfterAppendingChanges)") 
     return false 
    } 

    textField.layer.borderColor = UIColor.clearColor().CGColor   
    return true 
} 
+1

спасибо, что я получил его !!!! –