RxSwift学习:RxCocoa基础(一)

2,383 阅读3分钟

UILabel

文字绑定到 UILabel

let label = UILabel()
// ...
/// 值绑定
Observable.just("Hello RxSwift")
    .bind(to: label.rx.text)
    .disposed(by: disposeBag)

UITextField

监听单个 textField 内容的变化

方式一:

let textField = UITextField()
// ...
textField.rx.text.orEmpty.asObservable().subscribe(onNext: {
    print("你输入的是: \($0)")
}).disposed(by: disposeBag)

方式二:

let textField = UITextField()
// ...
textField.rx.text.orEmpty.changed.subscribe(onNext: {
    print("你输入的是: \($0)")
}).disposed(by: disposeBag)

监听多个 textField 内容的变化

let inputField1 = UITextField()
let inputField2 = UITextField()
// ...
Observable.combineLatest(inputField1.rx.text.orEmpty, inputField2.rx.text.orEmpty) {
    (textValue1, textValue2) in
        print("你输入的号码是: \(textValue1)-\(textValue2)")
}

将内容绑定到其他控件上

Binder 方式实现

let inputField  = UITextField()
let outputField = UITextField()
let label = UILabel()
let button = UIButton()
// ...
// UITextField --> UITextField
inputField.rx.text
    .bind(to: outputField.rx.text)
    .disposed(by: disposeBag)

// UITextField --> UILabel
inputField.rx.text
    .bind(to: label.rx.text)
    .disposed(by: disposeBag)

// UITextField --> UIButton
inputField.rx.text
    .map({ $0.count > 5 })
    .bind(to: button.rx.isEnabled)
    .disposed(by: disposeBag)

Driver 方式实现

let inputField  = UITextField()
let outputField = UITextField()
let label = UILabel()
let button = UIButton()
// ...
// UITextField --> UITextField
inputField.rx.text.orEmpty.asDriver()
    .drive(outputField.rx.text)
    .disposed(by: disposeBag)

// UITextField --> UILabel
inputField.rx.text
    .drive(label.rx.text)
    .disposed(by: disposeBag)

// UITextField --> UIButton
inputField.rx.text.orEmpty
    .asDriver()
    .map({ $0.count > 5 })
    .drive(button.rx.isEnabled)
    .disposed(by: disposeBag)

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

  • editingDidBegin:开始编辑(开始输入内容)
  • editingChanged:输入内容发生改变
  • editingDidEnd:结束编辑
  • editingDidEndOnExit:按下 return 键结束编辑
  • allEditingEvents:包含前面的所有编辑相关事件
let inputField1 = UITextField()
let inputField2 = UITextField()
// ...
inputField1.rx.controlEvent([.editingDidBegin]).asObservable().subscribe(onNext: {
    print("开始编辑")
}).disposed(by: disposeBag)

inputField1.rx.controlEvent([.editingDidEndOnExit]).subscribe(onNext: {
    inputField2.becomeFirstResponder()
}).disposed(by: disposeBag)

inputField2.rx.controlEvent([.editingDidEndOnExit]).subscribe(onNext: {
    inputField2.resignFirstResponder()
}).disposed(by: disposeBag)

UITextView

UITextView 包含了 UITextField 的方法 UITextView 独有的方法

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

  • didEndEditing:结束编辑
  • didChange:编辑内容发生改变
  • didChangeSelection:选中部分发生变化
let textView = UITextView()
// ...
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)

UIButton

按钮点击事件的绑定

let button = UIButton()
// ...
button.rx.tap.subscribe(onNext: {
    print("我被点击了")
}).disposed(by: disposeBag)

/// 另一种写法
button.rx.tap.bind {
    print("我也被点击了")
}.disposed(by: disposeBag)

按钮属性值的绑定

let button = UIButton()
// ...
Observable.just("Click Me")
    .bind(to: button.rx.title(for: .normal))
    .disposed(by: disposeBag)

Observable.just(UIImage(named: "imageName"))
    .bind(to: button.rx.image())
    .disposed(by: disposeBag)

let switch1 = UISwitch()
switch1.rx.isOn.bind(to: button.rx.isEnabled)
    .disposed(by: disposeBag)

UISlider

let slider = UISlider()
// ...
slider.rx.value.subscribe(onNext: {
    print("当前slider值为: \($0)")
}).disposed(by: disposeBag)

UIStepper

let stepper = UIStepper()
// ...
stepper.rx.value.subscribe(onNext: {
    print("当前stepper值为: \($0)")
}).disposed(by: disposeBag)

Slider 与 Stepper 绑定

let slider = UISlider()
let stepper = UIStepper()
// ...
// slider -> stepper
slider.rx.value.map{ Double($0) }
    .bind(to: stepper.rx.value)
    .disposed(by: disposeBag)

// stepper -> slider
stepper.rx.value.map{ Float($0) }
    .bind(to: slider.rx.value)
    .disposed(by: disposeBag)

UISwitch

let `switch` = UISwitch()
let button = UIButton()
let activityView = UIActivityIndicatorView()
// ...
`switch`.rx.value
    .bind(to: activityView.rx.isAnimating)
    .disposed(by: disposeBag)

`switch`.rx.isOn
    .bind(to: UIApplication.shared.rx.isNetworkActivityIndicatorVisible)
    .disposed(by: disposeBag)

/// 按钮和switch 之间的绑定
`switch`.rx.isOn.bind(to: button.rx.isEnabled).disposed(by: disposeBag)

UISegmentedControl

let segmentControl = UISegmentedControl()
// ...
segmentControl.rx.selectedSegmentIndex.subscribe(onNext: {
    print("当前页: \($0)")
}).disposed(by: disposeBag)

UIGestureRecognizer

RxCocoa + UIGestureRecognizer

let tapGesture = UITapGestureRecognizer()
view.addGestureRecognizer(tapGesture)

Tap

// 订阅方式实现
tapGesture.rx.event.subscribe(onNext: { _ in
    print("tapped")
}).disposed(by: disposeBag)

// 绑定方式实现
tapGesture.rx.event.bind { _ in
    print("tapped")
}.disposed(by: disposeBag)

Swipe

// 添加一个上滑的手势
let swipe = UISwipeGestureRecognizer()
swipe.direction = .up
self.view.addGestureRecognizer(swipe)

// 订阅方式实现
swipe.rx.event.subscribe(onNext: { [weak self] recognizer in
    let point = recognizer.location(in: self?.view)
    print("向上滑动 \(point.x) - \(point.y)")
}).disposed(by: disposeBag)

// 绑定方式实现
swipe.direction = .down
swipe.rx.event.bind { [weak self] recognizer in
    let point = recognizer.location(in: self?.view)
    print("向下滑动 \(point.x) - \(point.y)")
}.disposed(by: disposeBag

RxGesture + UIGestureRecognizer

tapView = UIView()
// ...
view.addSubview(tapView)

Tap

// tap
tapView.rx.tapGesture().when(.recognized)
    .subscribe(onNext: { _ in
    print("Tapped!!!")
}).disposed(by: disposeBag)

// double tap
tapView.rx.tapGesture(numberOfTapsRequired: 2).when(.recognized)
    .subscribe(onNext: { _ in
    print("double tapped!!!")
}).disposed(by: disposeBag)

Swipe

// swipe down
tapView.rx.swipeGesture(.down).when(.recognized)
    .subscribe(onNext: { _ in
    print("Swipe down")
}).disposed(by: disposeBag)

// swipe horizontal
tapView.rx.swipeGesture([.left, .right])
    .subscribe(onNext: { _ in
    print("Swipe horizontal")
}).disposed(by: disposeBag)

Long press

// long press
tapView.rx.longPressGesture().when(.began)
    .subscribe(onNext: { _ in
    print("long press")
}).disposed(by: disposeBag)

Pan

// pan gesture
let panGesture = tapView.rx.panGesture().share(replay: 1)

panGesture.when(.changed).asTranslation()
    .subscribe(onNext: { [unowned self] translation, _ in
    self.tapView.transform = CGAffineTransform(translationX: translation.x, y: translation.y)
}).disposed(by: disposeBag)

panGesture.when(.ended).subscribe(onNext: { _ in
    print("pan gesture end")
}).disposed(by: disposeBag)

Rotation Gesture

// rotation gesture
let rotationGesture = tapView.rx.rotationGesture().share(replay: 1)

rotationGesture.when(.changed).asRotation()
    .subscribe(onNext: { [unowned self] rotation, _ in
    self.tapView.transform = CGAffineTransform(rotationAngle: rotation)
}).disposed(by: disposeBag)

rotationGesture.when(.ended)
    .subscribe(onNext: { _ in
    print("rotation gesture end")
}).disposed(by: disposeBag)

Pinch

// 缩放 pinch
let pinchGesture = tapView.rx.pinchGesture().share(replay: 1)

pinchGesture.when(.changed)
    .asScale()
    .subscribe(onNext: { [unowned self] scale, _ in
    self.tapView.transform = CGAffineTransform(scaleX: scale, y: scale)
}).disposed(by: disposeBag)

pinchGesture.when(.ended)
    .subscribe(onNext: { _ in
        print("pinch end")
    }).disposed(by: disposeBag)

Edge Pan

// 边缘平移 EdgePan
view.rx.screenEdgePanGesture(edges: .right)
    .when(.recognized)
    .subscribe(onNext: { _ in
    print("rigjt edge")
}).disposed(by: disposeBag)

tapView.rx.anyGesture(.tap(), .swipe([.up, .right]))
    .when(.recognized)
    .subscribe(onNext: { _ in
    print("tap or up down")
}).disposed(by: disposeBag)

收录自|地址

Swift书籍资料下载:下载地址