저번 Driver에 이어서 나머지 Trait들도 마저 다 살펴보려고 합니다.
Signal
signal은 Driver와 유사합니다.
하지만 Driver는 subscribe할 때 한번 replay 하는 반면, Signal은 그렇지 않습니다.
Driver와 Signal을 구독하게 되면 다음과 같이 replay 합니다.
PublishRelay와 BehaviorRelay과 같이 Signal은 구독 이후의 이벤트를 방출하고 Driver은 구독을 하면 가장 최근의 이벤트를 방출한다는 점에서 차이점이 있습니다.
ControlProperty
UI Element의 property를 나타내기 위한 Trait
특징
- 실패하지 않는다.
- share(replay: 1) 처럼 행동한다 - stateful, subscribe 호출 시 마지막 element가 생성되면 즉시 replay 한다.
- 메인 쓰레드에서 실행된다.
- 에러를 방출하지 않는다.
- deallocated될 때 complete된다
아래 예시를 통해서 자세히 살펴보겠습니다.
UISearchBar+Rx
extension Reactive where Base: UISearchBar {
/// Reactive wrapper for `text` property.
public var value: ControlProperty<String?> {
let source: Observable<String?> = Observable.deferred { [weak searchBar = self.base as UISearchBar] () -> Observable<String?> in
let text = searchBar?.text
return (searchBar?.rx.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBar(_:textDidChange:))) ?? Observable.empty())
.map { a in
return a[1] as? String
}
.startWith(text)
}
let bindingObserver = Binder(self.base) { (searchBar, text: String?) in
searchBar.text = text
}
return ControlProperty(values: source, valueSink: bindingObserver)
}
}
UISegmentedControl+Rx
extension Reactive where Base: UISegmentedControl {
/// Reactive wrapper for `selectedSegmentIndex` property.
public var selectedSegmentIndex: ControlProperty<Int> {
value
}
/// Reactive wrapper for `selectedSegmentIndex` property.
public var value: ControlProperty<Int> {
return UIControl.rx.value(
self.base,
getter: { segmentedControl in
segmentedControl.selectedSegmentIndex
}, setter: { segmentedControl, value in
segmentedControl.selectedSegmentIndex = value
}
)
}
}
ControlEvent
controlProverty와 같이 UI Element의 property를 나타내기 위한 Trait
특징
- 실패하지 않는다.
- subscribe에게 초기값을 전달하지 않는다.
- 메인 쓰레드에서 실행된다.
- 에러를 방출하지 않는다.
- deallocated될 때 complete된다
public extension Reactive where Base: UIViewController {
/// Reactive wrapper for `viewDidLoad` message `UIViewController:viewDidLoad:`.
public var viewDidLoad: ControlEvent<Void> {
let source = self.methodInvoked(#selector(Base.viewDidLoad)).map { _ in }
return ControlEvent(events: source)
}
}
extension Reactive where Base: UICollectionView {
/// Reactive wrapper for `delegate` message `collectionView:didSelectItemAtIndexPath:`.
public var itemSelected: ControlEvent<IndexPath> {
let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didSelectItemAt:)))
.map { a in
return a[1] as! IndexPath
}
return ControlEvent(events: source)
}
}
'IOS🍎 > RxSwift' 카테고리의 다른 글
[RxSwift] Error Handling Operator (0) | 2022.05.10 |
---|---|
[RxSwift] Schedular란 (subscribeOn, observeOn) (0) | 2022.04.29 |
[RxSwift] Driver란 ? (feat. bind) (0) | 2022.03.21 |
[RxSwift] Traits 이란 (0) | 2022.03.19 |
[RxSwift] Disposable DisposeBag 이란 (0) | 2022.03.17 |
댓글