1, Listen for changes in the contents of a single textField (the same applies to textView)
- Display the contents entered in textField to the console in real time. Example code:
// Create text entry box let textField = UITextField(frame: CGRect(x:10, y:80, width:200, height:30)) textField.borderStyle = UITextField.BorderStyle.roundedRect self.view.addSubview(textField) // When the content of the text box changes, the content is output to the console textField.rx.text.orEmpty.asObservable() .subscribe(onNext: { print("You entered:\($0)") }) .disposed(by: disposeBag)
- . orEmpty can set String? The ControlProperty of type is converted to String to avoid unpacking again.
- The effects are as follows:
You entered: 1 You entered: 12 You entered: 123 You entered: 1234 You entered: 12345 You entered: 123456 You entered: 1234567 You entered: 12345678 You entered: 123456789 You entered: 1234567890
2, Bind content to other controls
- Desired effects:
-
- Display the contents entered in the first textField to the second textField in real time;
-
- At the same time, the current number of words will be displayed in label in real time;
-
- The "submit" button at the bottom will determine whether it is available according to the current number of words (only when the number of words exceeds 5).
- Example code:
let disposeBag = DisposeBag() // Create text entry box let inputField = UITextField(frame: CGRect(x:50, y:80, width:200, height:30)) inputField.borderStyle = UITextField.BorderStyle.roundedRect self.view.addSubview(inputField) // Create text output box let outputField = UITextField(frame: CGRect(x:50, y:150, width:200, height:30)) outputField.borderStyle = UITextField.BorderStyle.roundedRect self.view.addSubview(outputField) // Create text label let label = UILabel(frame:CGRect(x:60, y:190, width:300, height:30)) self.view.addSubview(label) // Create button let button:UIButton = UIButton(type:.system) button.frame = CGRect(x:60, y:230, width:40, height:30) button.setTitle("Submit", for:.normal) self.view.addSubview(button) // When the content of the text box changes let input = inputField.rx.text.orEmpty.asDriver() // Convert normal sequence to Driver .throttle(0.3) // Operate in the main thread. If the value changes many times within 0.3 seconds, take the last time // Bind content to another input box input.drive(outputField.rx.text) .disposed(by: disposeBag) // Bind content to text labels input.map{ "Current number of words:\($0.count)" } .drive(label.rx.text) .disposed(by: disposeBag) // Determine whether the button is available according to the number of words in the content input.map{ $0.count > 5 } .drive(button.rx.isEnabled) .disposed(by: disposeBag)
- Operation effect:
- Throttling is a feature of RxSwift, because when something changes, it usually does a lot of logical operations. Using the throttling feature will not produce a large number of logical operations, but will be performed in a small and reasonable range. For example, this feature is very useful when doing some real-time search functions.
3, Monitor the content changes of multiple textfields at the same time (the same is true for textView)
- Desired effects:
-
- There are two input boxes on the interface, which are used to fill in the area code and number of the telephone respectively;
-
- No matter which input box changes, they will be spelled into a complete number and displayed in the label.
- Example code:
let disposeBag = DisposeBag() // Create text entry box let inputField = UITextField(frame: CGRect(x:50, y:80, width:200, height:30)) inputField.borderStyle = UITextField.BorderStyle.roundedRect self.view.addSubview(inputField) // Create text output box let outputField = UITextField(frame: CGRect(x:50, y:150, width:200, height:30)) outputField.borderStyle = UITextField.BorderStyle.roundedRect self.view.addSubview(outputField) // Create text label let label = UILabel(frame:CGRect(x:60, y:190, width:300, height:30)) self.view.addSubview(label) Observable.combineLatest(inputField.rx.text.orEmpty, outputField.rx.text.orEmpty) { textValue1, textValue2 -> String in return "The number you entered is:\(textValue1)-\(textValue2)" } .map { $0 } .bind(to: label.rx.text) .disposed(by: disposeBag)
- Operation effect:
4, Event listening
- Various events in the input box can be monitored through rx.controlEvent, and multiple event states can be combined freely. In addition to the touch events of various UI controls, the input box also has the following unique events:
-
- editingDidBegin: start editing (start entering content)
-
- editingChanged: the input content has changed
-
- editingDidEnd: end editing
-
- editingDidEndOnExit: press the return key to end editing
-
- allEditingEvents: contains all previous editing related events
- Listen to the input box to start editing the event (get the focus) and respond accordingly:
textField.rx.controlEvent([.editingDidBegin]) //States can be combined .asObservable() .subscribe(onNext: { _ in print("Start editing content!") }).disposed(by: disposeBag)
- Add two input boxes on the interface to input user name and password respectively:
-
- If the current focus is in the user name input box, the focus will automatically shift to the password input box when you press the return key;
-
- If the current focus is in the password input box, the focus will be automatically removed when you press the return key.
// Press the return key in the user name input box username.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: { [weak self] (_) in self?.password.becomeFirstResponder() }).disposed(by: disposeBag) // Press the return key in the password input box password.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: { [weak self] (_) in self?.password.resignFirstResponder() }).disposed(by: disposeBag)
5, UITextView specific methods
- UITextView also encapsulates the following delegate callback methods:
-
- Didbiginediting: start editing
-
- didEndEditing: end editing
-
- didChange: the editing content has changed
-
- didChangeSelection: the selected part changes
- Use example:
// Start editing response textView.rx.didBeginEditing .subscribe(onNext: { print("Start editing") }) .disposed(by: disposeBag) // End editing response textView.rx.didEndEditing .subscribe(onNext: { print("End editing") }) .disposed(by: disposeBag) // Content change response textView.rx.didChange .subscribe(onNext: { print("Content changes") }) .disposed(by: disposeBag) // Select partial change response textView.rx.didChangeSelection .subscribe(onNext: { print("The selected part changes") }) .disposed(by: disposeBag)