Apple程序员RxSwift学习

Swift - RxSwift的使用详解22(UI控件扩展2:U

2018-03-20  本文已影响2578人  八级大狂风AM

二、UITextField 与 UITextView

1,监听单个 textField 内容的变化(textView 同理)

(1)下面样例中我们将 textField 里输入的内容实时地显示到控制台中。

(2)样例代码

注意.orEmpty 可以将 String? 类型的 ControlProperty 转成 String,省得我们再去解包。

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag()
     
    override func viewDidLoad() {
         
        //创建文本输入框
        let textField = UITextField(frame: CGRect(x:10, y:80, width:200, height:30))
        textField.borderStyle = UITextBorderStyle.roundedRect
        self.view.addSubview(textField)
         
        //当文本框内容改变时,将内容输出到控制台上
        textField.rx.text.orEmpty.asObservable()
            .subscribe(onNext: {
                print("您输入的是:\($0)")
            })
            .disposed(by: disposeBag)
    }
}

(3)当然我们直接使用 change 事件效果也是一样的。

//当文本框内容改变时,将内容输出到控制台上
textField.rx.text.orEmpty.changed
    .subscribe(onNext: {
        print("您输入的是:\($0)")
    })
    .disposed(by: disposeBag)

2,将内容绑定到其他控件上

(1)效果图

(2)样例代码

Throttling 的作用

ThrottlingRxSwift 的一个特性。因为有时当一些东西改变时,通常会做大量的逻辑操作。而使用 Throttling 特性,不会产生大量的逻辑操作,而是以一个小的合理的幅度去执行。比如做一些实时搜索功能时,这个特性很有用。

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag()
     
    override func viewDidLoad() {
         
        //创建文本输入框
        let inputField = UITextField(frame: CGRect(x:10, y:80, width:200, height:30))
        inputField.borderStyle = UITextBorderStyle.roundedRect
        self.view.addSubview(inputField)
         
        //创建文本输出框
        let outputField = UITextField(frame: CGRect(x:10, y:150, width:200, height:30))
        outputField.borderStyle = UITextBorderStyle.roundedRect
        self.view.addSubview(outputField)
         
        //创建文本标签
        let label = UILabel(frame:CGRect(x:20, y:190, width:300, height:30))
        self.view.addSubview(label)
         
        //创建按钮
        let button:UIButton = UIButton(type:.system)
        button.frame = CGRect(x:20, y:230, width:40, height:30)
        button.setTitle("提交", for:.normal)
        self.view.addSubview(button)
         
         
        //当文本框内容改变
        let input = inputField.rx.text.orEmpty.asDriver() // 将普通序列转换为 Driver
            .throttle(0.3) //在主线程中操作,0.3秒内值若多次改变,取最后一次
         
        //内容绑定到另一个输入框中
        input.drive(outputField.rx.text)
            .disposed(by: disposeBag)
         
        //内容绑定到文本标签中
        input.map{ "当前字数:\($0.count)" }
            .drive(label.rx.text)
            .disposed(by: disposeBag)
         
        //根据内容字数决定按钮是否可用
        input.map{ $0.count > 5 }
            .drive(button.rx.isEnabled)
            .disposed(by: disposeBag)
    }
}

3,同时监听多个 textField 内容的变化(textView 同理)

(1)效果图

(2)样例代码

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag()
     
    @IBOutlet weak var textField1: UITextField!
    @IBOutlet weak var textField2: UITextField!
    @IBOutlet weak var label: UILabel!
     
    override func viewDidLoad() {
         
        Observable.combineLatest(textField1.rx.text.orEmpty, textField2.rx.text.orEmpty) {
            textValue1, textValue2 -> String in
            return "你输入的号码是:\(textValue1)-\(textValue2)"
            }
            .map { $0 }
            .bind(to: label.rx.text)
            .disposed(by: disposeBag)
    }
}

4,事件监听

(1)通过 rx.controlEvent 可以监听输入框的各种事件,且多个事件状态可以自由组合。除了各种 UI 控件都有的 touch 事件外,输入框还有如下几个独有的事件:

(2)下面代码监听输入框开始编辑事件(获取到焦点)并做相应的响应。

textField.rx.controlEvent([.editingDidBegin]) //状态可以组合
    .asObservable()
    .subscribe(onNext: { _ in
        print("开始编辑内容!")
    }).disposed(by: disposeBag)

(3)下面代码我们在界面上添加两个输入框分别用于输入用户名和密码:

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
 
    //用户名输入框
    @IBOutlet weak var username: UITextField!
     
    //密码输入框
    @IBOutlet weak var password: UITextField!
     
    let disposeBag = DisposeBag()
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        //在用户名输入框中按下 return 键
        username.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: {
            [weak self] (_) in
            self?.password.becomeFirstResponder()
        }).disposed(by: disposeBag)
         
         //在密码输入框中按下 return 键
        password.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: {
            [weak self] (_) in
            self?.password.resignFirstResponder()
        }).disposed(by: disposeBag)
    }
}

附:UITextView 独有的方法

(1)UITextView 还封装了如下几个委托回调方法:

(2)使用样例

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag()
     
    @IBOutlet weak var textView: UITextView!
     
    override func viewDidLoad() {
         
        //开始编辑响应
        textView.rx.didBeginEditing
            .subscribe(onNext: {
                print("开始编辑")
            })
            .disposed(by: disposeBag)
         
        //结束编辑响应
        textView.rx.didEndEditing
            .subscribe(onNext: {
                print("结束编辑")
            })
            .disposed(by: disposeBag)
         
        //内容发生变化响应
        textView.rx.didChange
            .subscribe(onNext: {
                print("内容发生改变")
            })
            .disposed(by: disposeBag)
         
        //选中部分变化响应
        textView.rx.didChangeSelection
            .subscribe(onNext: {
                print("选中部分发生变化")
            })
            .disposed(by: disposeBag)
    }
}

RxSwift使用详解系列
原文出自:www.hangge.com转载请保留原文链接

上一篇下一篇

猜你喜欢

热点阅读