관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 2. UITextField, UITextView에서 알면 좋은 개념 - binding (rx.text, editingChanged, allEditingEvents, shouldChangeCharactersIn, allEditingEvents) 본문

iOS 응용 (swift)

[iOS - swift] 2. UITextField, UITextView에서 알면 좋은 개념 - binding (rx.text, editingChanged, allEditingEvents, shouldChangeCharactersIn, allEditingEvents)

jake-kim 2023. 12. 1. 00:34

1. UITextField, UITextView에서 알면 좋은 개념 - deleteBackward()

2. UITextField, UITextView에서 알면 좋은 개념 - binding (rx.text, editingChanged, allEditingEvents,  shouldChangeCharactersIn, allEditingEvents)

3. UITextField, UITextView에서 알면 좋은 개념 - NSRange, UITextRange (#utf16)

4. UITextField, UITextView에서 알면 좋은 개념 - prefix, suffix, insert

text 바인딩

  • text가 변할 때 실시간으로 이벤트를 받는 것
  • 가장 알려진 메서드는 델리게이트 메서드 중 하나인 shouldChangeCharactrersIn 메서드
extension ViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        print("shouldChangeCharactersIn>", textField.text!, string)
        return true
    }
}
  • text 바인딩 중 핵심 내용은 코드로 textField.text에 적용했을때, 이벤트를 캐치하는 바인딩을 구분하는  것

바인딩  비교

  • textField.text에 문자열을 대입했을때 이벤트가 호출하는 것이 'editingEvents'가 들어가면 호출됨
    • editingChanged: 키보드 입력 (o), textField.text 대입 (o)
    • allEditingEvents: 키보드 입력 (o), textField.text 대입 (o)
    • rx.text: 키보드 입력 (o), textField.text 대입 (o)
    • shouldChangeCharactersIn: 키보드 입력 (o), textField.text 대입 (x)

참고) rx.text는 내부적으로 allEditingEvents를 처리하고 있기 때문에 textField.text에 대입했을때 이벤트가 호출됨

https://github.com/ReactiveX/RxSwift/blob/main/RxCocoa/iOS/UITextField%2BRx.swift#L21
https://github.com/ReactiveX/RxSwift/blob/main/RxCocoa/iOS/UIControl%2BRx.swift#L73

테스트)

  • 버튼을 두고 이 버튼을 탭했을때 textField.text에 대입하도록 구현하고, textField에서 어떤 이벤트가 호출되는지 확인
button.addTarget(self, action: #selector(tap), for: .touchUpInside)

@objc private func tap() {
    textField.insertText("new ")
}
  • textField 바인딩
// 1.
textField.rx.text
    .bind { text in
        print("textView.rx.text>", text!)
    }
    .disposed(by: disposeBag)
    
// 2. 
textField.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
@objc private func editingChanged() {
    print("editingChanged>", textField.text!)
}

// 3. 
textField.addTarget(self, action: #selector(allEditingEvents), for: .allEditingEvents)
@objc private func allEditingEvents() {
    print("allEditingEvents> ", textField.text!)
}

// 4. 
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    print("shouldChangeCharactersIn>", textField.text!, string)
    return true
}

 

* 전체 코드: https://github.com/JK0369/ExTextBinding

* 참고

- https://github.com/ReactiveX/RxSwift/blob/main/RxCocoa/iOS/UITextField%2BRx.swift#L21

- https://github.com/ReactiveX/RxSwift/blob/main/RxCocoa/iOS/UIControl%2BRx.swift#L73

Comments