Binder는 이벤트를 방출시켜주는 유아이와 메핑하기 위환 ObserverType이다 라고 생각 하면 됨.
→ rxswift만으로도 구현이 가능하지만 rxCocoa를 사용하면 코드가 간결해 진다고 생각함.
/// Initializes `Binder`
///
/// - parameter target: Target object.
/// - parameter scheduler: Scheduler used to bind the events.
/// - parameter binding: Binding logic.
public init<Target: AnyObject>(_ target: Target,
scheduler: ImmediateSchedulerType = MainScheduler(),
binding: @escaping (Target, Value) -> Void) {
weak var weakTarget = target
self._binding = { event in
switch event {
case .next(let element):
_ = scheduler.schedule(element) { element in
if let target = weakTarget {
binding(target, element)
}
return Disposables.create()
}
case .error(let error):
bindingError(error)
case .completed:
break
}
}
}
target:Binder로 확장시킬 객체로 AnyObject 이기 때문에 오브젝트 타입만 접근이 가능함.
scheduler : UI객체를 위한 Observer이기 때문에 메인 스케쥴러에서 실행되게함. 위 코드처럼 next이벤트를 메인 스케슐러에서 돌게함.
binding : escaping 클로저로 확장시킬 객체와 값을 받아와 원하는 작업을 수행
extension Reactive where Base: UILabel {
/// Bindable sink for `text` property.
public var text: Binder<String?> {
return Binder(self.base) { label, text in
label.text = text
}
}
}
label.rx.text를 통해 접근이 가능한 Binder 확장 구현부이다. 바인더 인잇메소드를 호출하며 첫번째 파라메 터로 UILabel객체를 전달, 스케줄러는 생략, 클로저로 label과 string값을 전달해 내부에서 라벨의 텍스트 값을 변경하는 기능을함.
UI객체의 특정 프로퍼티와 매핑시키는 함수
버튼 텝하면 라벨의 숫자가 수정됨
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let disposeBag = DisposeBag()
@IBOutlet weak var button: UIButton!
@IBOutlet weak var label: UILabel!
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
bind()
}
func bind(){
button.rx.tap//탭하면 이벤트를 수신하겠다
.map{ [weak self] ()->String? in
guard let self = self else {return nil}
self.count+=1
return "\\(self.count)"
}//() 를 -> String 으로 변경하겠다.
.bind(to: label.rx.text)//label의 text필드로 스트링값을 바인딩하겠다.
.disposed(by: disposeBag)
}
}