UITextField 텍스트 변경 이벤트
textField에서 텍스트 변경 사항을 어떻게 감지합니까? 대리자 메서드가 shouldChangeCharactersInRange
작동하지만 내 요구를 정확하게 충족시키지 못했습니다. YES를 반환 할 때까지 textField 텍스트는 다른 관찰자 메서드에서 사용할 수 없습니다.
예를 들어 내 코드 calculateAndUpdateTextFields
에서 업데이트 된 텍스트를 얻지 못하면 사용자가 입력했습니다.
textChanged
Java 이벤트 핸들러 와 같은 것을 얻을 수있는 방법 입니다.
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
if (textField.tag == kTextFieldTagSubtotal
|| textField.tag == kTextFieldTagSubtotalDecimal
|| textField.tag == kTextFieldTagShipping
|| textField.tag == kTextFieldTagShippingDecimal)
{
[self calculateAndUpdateTextFields];
}
return YES;
}
에서 적절한 방법 텍스트 변경 콜 다시 UITextField에해야 할 일 :
UITextField 컨트롤에 보낸 문자를 다음과 같이 잡습니다.
// Add a "textFieldDidChange" notification method to the text field control.
Objective-C에서 :
[textField addTarget:self
action:@selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
스위프트에서 :
textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
그런 다음
textFieldDidChange
메소드에서 textField의 내용을 검사하고 필요에 따라 테이블 뷰를 다시로드 할 수 있습니다.
그것을 사용하고 calculateAndUpdateTextFields를 으로 넣을 수 있습니다 selector
.
XenElement의 답변이 제자리에 있습니다.
UITextField를 마우스 오른쪽 버튼으로 클릭하고 "Editing Changed"송신 이벤트를 서브 클래스 유닛으로 드래그하여 인터페이스 빌더에서도 위와 같은 작업을 수행 할 수 있습니다.
이벤트 리스너를 설정하려면 다음을 수행하십시오.
[self.textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
실제로 들으려면 :
- (void)textFieldDidChange:(UITextField *)textField {
NSLog(@"text changed: %@", textField.text);
}
빠른:
yourTextfield.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
그런 다음 콜백 함수를 구현하십시오.
@objc func textFieldDidChange(textField: UITextField){
print("Text changed")
}
여기에 언급 된 바와 같이 : UITextField 텍스트 변경 이벤트 , iOS 6 (iOS 6.0 및 6.1 확인)에서는 UITextField
을 관찰하여 객체의 변경 사항을 완전히 감지 할 수없는 것으로 보입니다 UITextFieldTextDidChangeNotification
.
내장 iOS 키보드로 직접 변경 한 내용 만 추적되는 것 같습니다. 즉 , UITextField
다음과 같이 호출 하여 객체 를 변경하면 변경 myUITextField.text = @"any_text"
사항에 대한 알림이 전혀 표시되지 않습니다.
이것이 버그인지 또는 의도 된 것인지 모르겠습니다. 문서에서 합리적인 설명을 찾지 못했기 때문에 버그처럼 보입니다. UITextField text change event 에도 설명 되어 있습니다 .
이것에 대한 나의 "솔루션"은 실제로 내가 변경할 때마다 UITextField
(내장 iOS 키보드를 사용하지 않고 변경이 이루어진 경우) 스스로 알림을 게시하는 것입니다 . 이 같은:
myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";
NSNotification *myTextFieldUpdateNotification =
[NSNotification notificationWithName:UITextFieldTextDidChangeNotification
object:myUITextField];
[NSNotificationCenter.defaultCenter
postNotification:myTextFieldUpdateNotification];
이렇게하면 코드에서 "수동으로"업데이트하거나 내장 iOS 키보드를 통해 객체 의 .text
속성 을 변경할 때 동일한 알림을받을 것이라는 100 % 확신을 갖게 UITextField
됩니다.
문서화 된 동작이 아니기 때문에이 방법을 사용하면 UITextField
객체 의 동일한 변경에 대해 2 개의 알림이 수신 될 수 있습니다 . 필요에 따라 ( UITextField.text
변경할 때 실제로 수행하는 작업 ) 이는 불편할 수 있습니다.
알림이 UITextFieldTextDidChangeNotification
자신의 알림인지 "iOS-made"인지 실제로 알아야하는 경우 약간 다른 방법으로 사용자 지정 알림 (이 아닌 사용자 지정 이름으로)을 게시하는 것입니다.
편집하다:
방금 더 나은 것으로 생각되는 다른 접근법을 찾았습니다.
여기에는 Objective-C의 KVO (Key-Value Observing) 기능 ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid / 10000177-BCICJDHA ).
기본적으로 귀하는 자신을 속성의 관찰자로 등록하고이 속성이 변경되면 이에 대한 알림을받습니다. "원칙"은 NSNotificationCenter
작동 방식 과 매우 유사하며 ,이 접근 방식은 iOS 6에서 자동으로 작동한다는 주요 이점입니다 (수동으로 알림을 게시하는 것과 같은 특별한 조정없이).
우리에 대한 UITextField
당신의 당신이 예를 들어,이 코드를 추가 할 경우이 잘 작동 -scenario, UIViewController
텍스트 필드를 포함 :
static void *myContext = &myContext;
- (void)viewDidLoad {
[super viewDidLoad];
//Observing changes to myUITextField.text:
[myUITextField addObserver:self forKeyPath:@"text"
options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld
context:myContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if(context == myContext) {
//Here you get notified every time myUITextField's "text" property is updated
NSLog(@"New value: %@ - Old value: %@",
[change objectForKey:NSKeyValueChangeNewKey],
[change objectForKey:NSKeyValueChangeOldKey]);
}
else
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
"컨텍스트"관리와 관련된이 답변의 출처 : https://stackoverflow.com/a/12097161/2078512
참고 : 당신이 동안 것 같다 과정에서 을 편집 UITextField
내장 된 아이폰 OS 키보드, 텍스트 필드의 "텍스트"속성은 모든 새로운 문자로 업데이트되지 않습니다으로 입력 / 제거. 대신 텍스트 필드의 첫 번째 응답자 상태를 사임 한 후 텍스트 필드 개체가 "전체로"업데이트됩니다.
Storyboard
CTRL 에서 @IBAction
다음과 같이 이벤트를 쉽게 변경하고 구성 할 수 있습니다
빠른 버전으로 여기에 동일합니다.
textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
func textFieldDidChange(textField: UITextField) {
}
감사
shouldChangeChractersInRange의 동작을 변경하는 문제를 해결했습니다. NO를 반환하면 iOS에서 변경 사항을 내부적으로 적용하지 않고 대신 수동으로 변경하고 변경 후 작업을 수행 할 수 있습니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//Replace the string manually in the textbox
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
//perform any logic here now that you are sure the textbox text has changed
[self didChangeTextInTextField:textField];
return NO; //this make iOS not to perform any action
}
스위프트 버전 테스트 :
//Somewhere in your UIViewController, like viewDidLoad(){ ... }
self.textField.addTarget(
self,
action: #selector(SearchViewController.textFieldDidChange(_:)),
forControlEvents: UIControlEvents.EditingChanged
)
설명 된 매개 변수 :
self.textField //-> A UITextField defined somewhere in your UIViewController
self //-> UIViewController
.textFieldDidChange(_:) //-> Can be named anyway you like, as long as it is defined in your UIViewController
그런 다음 위에서 만든 방법을 다음에 추가하십시오 UIViewController
.
//Gets called everytime the text changes in the textfield.
func textFieldDidChange(textField: UITextField){
print("Text changed: " + textField.text!)
}
스위프트 4
func addNotificationObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(textFieldDidChangeAction(_:)), name: .UITextFieldTextDidChange, object: nil)
}
@objc func textFieldDidChangeAction(_ notification: NSNotification) {
let textField = notification.object as! UITextField
print(textField.text!)
}
스위프트 3.0 :
let textField = UITextField()
textField.addTarget(
nil,
action: #selector(MyClass.textChanged(_:)),
for: UIControlEvents.editingChanged
)
다음과 같은 클래스를 사용하십시오.
class MyClass {
func textChanged(sender: Any!) {
}
}
스위프트 3 버전
yourTextField.addTarget(self, action: #selector(YourControllerName.textChanges(_:)), for: UIControlEvents.editingChanged)
그리고 여기에서 변화를 얻으십시오
func textChanges(_ textField: UITextField) {
let text = textField.text! // your desired text here
// Now do whatever you want.
}
도움이 되길 바랍니다.
다른 방법은 실제로 중국어 입력 방법을 사용할 때 실제로 입력되지 않은 입력 상자를 수신하기 때문에이 문제를 해결하려면 알림을 사용해야합니다. viewDidload에서
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFiledEditChanged:)
name:@"UITextFieldTextDidChangeNotification"
object:youTarget];
그때
- (void)textFiledEditChanged:(NSNotification *)obj {
UITextField *textField = (UITextField *)obj.object;
NSString *toBestring = textField.text;
NSArray *currentar = [UITextInputMode activeInputModes];
UITextInputMode *currentMode = [currentar firstObject];
if ([currentMode.primaryLanguage isEqualToString:@"zh-Hans"]) {
UITextRange *selectedRange = [textField markedTextRange];
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
if (!position) {
if (toBestring.length > kMaxLength)
textField.text = toBestring;
}
}
마지막으로, 당신은 실행됩니다.
스위프트 3.1 :
선택기 : ClassName.MethodName
cell.lblItem.addTarget(self, action: #selector(NewListScreen.fieldChanged(textfieldChange:)), for: .editingChanged)
func fieldChanged(textfieldChange: UITextField){
}
폐쇄와 함께 :
class TextFieldWithClosure: UITextField {
var targetAction: (() -> Void)? {
didSet {
self.addTarget(self, action: #selector(self.targetSelector), for: .editingChanged)
}
}
func targetSelector() {
self.targetAction?()
}
}
그리고 사용
textField.targetAction? = {
// will fire on text changed
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didChangeTextViewText:)
name:UITextFieldTextDidChangeNotification object:nil];
- (void) didChangeTextViewText {
//do something
}
스위프트 3 버전 :
class SomeClass: UIViewController, UITextFieldDelegate {
@IBOutlet weak var aTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
aTextField.delegate = self
aTextField.addTarget(self, action: #selector(SignUpVC.textFieldDidChange), for: UIControlEvents.editingChanged)
}
func textFieldDidChange(_ textField: UITextField) {
//TEXT FIELD CHANGED..SECRET STUFF
}
}
델리게이트를 설정하는 것을 잊지 마십시오.
스위프트 4 버전
키-값 관찰 사용 다른 객체의 속성 변경에 대해 객체에 알립니다.
var textFieldObserver: NSKeyValueObservation?
textFieldObserver = yourTextField.observe(\.text, options: [.new, .old]) { [weak self] (object, changeValue) in
guard let strongSelf = self else { return }
print(changeValue)
}
관찰자와 반응성 신속한 (RxCocoa & RxSwift)으로 정말 간단합니다.
다음과 같이 rx의 text 속성을 구독하십시오.
myTextField.rx.text.subscribe { text in
print("UITextFieldTextChangeEvent Text:\(text)")
}.disposed(by: disposeBag)
참고 URL : https://stackoverflow.com/questions/7010547/uitextfield-text-change-event
'Programing' 카테고리의 다른 글
JavaScript에서 연관 배열 / 해싱을 수행하는 방법 (0) | 2020.02.10 |
---|---|
주어진 부분 이름으로 모든 프로세스를 종료하는 방법은 무엇입니까? (0) | 2020.02.10 |
nullptr은 정확히 무엇입니까? (0) | 2020.02.10 |
Babel 6 재생기 런타임이 정의되지 않았습니다 (0) | 2020.02.09 |
Javascript에서 객체의 첫 번째 속성에 액세스하는 방법은 무엇입니까? (0) | 2020.02.09 |