을 UITextField
올릴 때 iPhone SDK 에서 최대 문자 수를 어떻게 설정 UIView
합니까?
답변
그동안 UITextField
클래스에는 최대 길이 속성이 없습니다, 그것은 텍스트 필드의를 설정하여이 기능을 얻기 위해 상대적으로 간단 delegate
하고 다음 대리자 메서드를 구현 :
목표 -C
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Prevent crashing undo bug – see note below.
if(range.length + range.location > textField.text.length)
{
return NO;
}
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return newLength <= 25;
}
빠른
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentCharacterCount = textField.text?.count ?? 0
if range.length + range.location > currentCharacterCount {
return false
}
let newLength = currentCharacterCount + string.count - range.length
return newLength <= 25
}
텍스트 필드가 변경되기 전에 UITextField는 지정된 텍스트 를 변경 해야하는지 대리인에게 묻습니다 . 이 시점에서 텍스트 필드는 변경되지 않았으므로 현재 길이와 삽입 할 문자열 길이 (복사 된 텍스트 붙여 넣기 또는 키보드를 사용하여 단일 문자 입력)를 빼고 범위 길이를 뺀 것입니다. 이 값이 너무 길면 (이 예에서는 25 자 이상) NO
변경을 금지하기 위해 돌아가십시오 .
텍스트 필드의 끝에 단일 문자를 입력 range.location
하면 현재 필드의 길이가되고 range.length
어떤 것도 바꾸거나 삭제하지 않기 때문에 0이됩니다. 텍스트 필드의 중간에 삽입한다는 것은 다른 것을 의미하며 range.location
여러 문자를 붙여 넣으면 string
둘 이상의 문자가 있음을 의미 합니다.
단일 문자 삭제 또는 여러 문자 절단은 range
길이가 0이 아닌 빈 문자열로 지정됩니다. 교체는 비어 있지 않은 문자열로 범위를 삭제하는 것입니다.
충돌하는 “실행 취소”버그에 대한 메모
주석에서 언급했듯이 UITextField
충돌이 발생할 수 있는 버그 가 있습니다.
필드에 붙여 넣지 만 유효성 검사 구현으로 붙여 넣기가 금지 된 경우 붙여 넣기 작업은 여전히 응용 프로그램의 실행 취소 버퍼에 기록됩니다. 당신이 후 (장치를 흔들어 실행 취소를 확인하여) 실행 취소를 해고하는 경우는 UITextField
이 문자열 대체하려고 시도합니다 생각 이 빈 문자열 자체에 붙여 넣기합니다. 실제로 문자열을 자체적으로 붙여 넣지 않았기 때문에 충돌이 발생 합니다. 존재하지 않는 문자열의 일부를 바꾸려고 시도합니다.
다행스럽게도 UITextField
이와 같이 자신을 죽이지 않도록 보호 할 수 있습니다 . 당신은 그것을 대체하는 제안의 범위가 있는지 확인해야 합니까 현재 문자열 내에 존재합니다. 이것이 위의 초기 상태 점검입니다.
swift 3.0 복사 및 붙여 넣기가 잘 작동합니다.
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let str = (textView.text + text)
if str.characters.count <= 10 {
return true
}
textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
return false
}
도움이 되길 바랍니다.
답변
스위프트 4
import UIKit
private var kAssociationKeyMaxLength: Int = 0
extension UITextField {
@IBInspectable var maxLength: Int {
get {
if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
return length
} else {
return Int.max
}
}
set {
objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
}
}
@objc func checkMaxLength(textField: UITextField) {
guard let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
let substring = prospectiveText[..<indexEndOfText]
text = String(substring)
selectedTextRange = selection
}
}
편집 : 메모리 누수 문제가 해결되었습니다.
답변
8 월 감사합니다! ( 포스트 )
이것은 내가 끝낸 코드입니다.
#define MAX_LENGTH 20
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= MAX_LENGTH && range.length == 0)
{
return NO; // return NO to not change text
}
else
{return YES;}
}
답변
제안 된 함수의 가능한 구현 인 8 월 답변 을 완료하려면 ( UITextField의 delegate 참조 ).
나는 돔 코드를 테스트 하지 않았지만 사용자가 한계에 도달하면 멈추지 않으며 더 작거나 같은 것을 대체하는 새로운 문자열과 호환됩니다.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//limit the size :
int limit = 20;
return !([textField.text length]>limit && [string length] > range.length);
}
답변
직접 할 수 UITextField
는 없습니다 -maxLength 속성이 없지만 UITextField's
대리자를 설정 한 후 다음을 사용할 수 있습니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
답변
종종 길이가 다른 여러 입력 필드가 있습니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int allowedLength;
switch(textField.tag) {
case 1:
allowedLength = MAXLENGTHNAME; // triggered for input fields with tag = 1
break;
case 2:
allowedLength = MAXLENGTHADDRESS; // triggered for input fields with tag = 2
break;
default:
allowedLength = MAXLENGTHDEFAULT; // length default when no tag (=0) value =255
break;
}
if (textField.text.length >= allowedLength && range.length == 0) {
return NO; // Change not allowed
} else {
return YES; // Change allowed
}
}
답변
가장 좋은 방법은 텍스트 변경에 대한 알림을 설정하는 것입니다. 당신의에서 -awakeFromNib
보기 컨트롤러 방법 당신이 원하는 것 :
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextField:) name:@"UITextFieldTextDidChangeNotification" object:myTextField];
그런 다음 동일한 클래스에서 다음을 추가하십시오.
- (void)limitTextField:(NSNotification *)note {
int limit = 20;
if ([[myTextField stringValue] length] > limit) {
[myTextField setStringValue:[[myTextField stringValue] substringToIndex:limit]];
}
}
그런 다음 콘센트 myTextField
를 귀하 의 콘센트 에 연결 UITextField
하면 한도에 도달 한 후 더 이상 문자를 추가 할 수 없습니다. 이것을 dealloc 메소드에 추가하십시오 :
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];