์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- CollectionView
- node.js
- tableView
- combine
- ํ๋ก๊ทธ๋๋จธ์ค
- BOJ
- SnapKit
- ios
- arkit
- raywenderlich
- reactorkit
- MVVM
- Xcode
- realm
- designpattern
- SwiftUI
- ํจ์คํธ์บ ํผ์ค
- visionOS
- TCA
- rxcocoa
- UIKit
- Kuring
- Flutter
- Lv2
- XCTest
- Swfit
- BFS
- ๋ฐฑ์ค
- swift
- RxSwift
- Today
- Total
lgvv98
[Swift] extension Reactive ๋ณธ๋ฌธ
โ ์ด๋ฒ ์๊ฐ์๋ extension Reactive์ ๋ํด์ ์์๋ณผ ์์ ์ด์ผ.
์ฐ๋ฆฌ๊ฐ ์ค์นํ RxSwfit ์์๋ Reactive.swift ํ์ผ์ด ์๋๋ฐ, custom point๋ก ์ฌ์ฉํ๋ผ๊ณ ํ๋ค.
๐ Reactive.swift
Use `Reactive` proxy as customization point for constrained protocol extensions.
General pattern would be:
// 1. Extend Reactive protocol with constrain on Base
// Read as: Reactive Extension where Base is a SomeType
extension Reactive where Base: SomeType {
// 2. Put any specific reactive extension for SomeType here
}
With this approach we can have more specialized methods and properties using
`Base` and not just specialized on common base type.
*/
public struct Reactive<Base> {
/// Base object to extend.
public let base: Base
/// Creates extensions with base object.
///
/// - parameter base: Base object.
public init(_ base: Base) {
self.base = base
}
}
โ ๊ทธ๋ ๋ค๋ฉด Reactive ์ด๋ฏธ ๊ตฌํ๋ RxSwift ํ์ผ์์๋ ์ด๋ป๊ฒ ์ฌ์ฉํ๊ณ ์์๊น?
extension Reactive where Base: UIButton {
/// Reactive wrapper for `TouchUpInside` control event.
public var tap: ControlEvent<Void> {
return controlEvent(.touchUpInside)
}
}
์ด๋ฐ์์ผ๋ก ๊ตฌํํ๊ณ ์๋ค.
๊ทธ๋ผ ์ฐ๋ฆฌ๋ ์ด์ ๋ง์ถฐ์ customํ๊ฒ๋ ๊ตฌํํ ์ ์๊ฒ ์ง?
โ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋ค์ด๊ฐ๊ธฐ ์ ์... ์์์ผ ํ 3๊ฐ์ง
1๏ธโฃ ControlEvent - ๊ฐ์ ๊ด์ฐฐํ ์๋ ์์ผ๋, ๊ฐ์ ์ฃผ์ ์ํค์ง๋ ๋ชปํจ.
2๏ธโฃ ControlProperty - ๊ฐ์ ์ฃผ์ ์ํฌ ์๋ ์๊ณ , ๊ฐ์ ๋ณํ๋ ๊ด์ฐฐํ ์ ์๋ค.
3๏ธโฃ Binder - ๊ฐ์ ์ฃผ์ ์ํฌ ์ ์์ผ๋, ๊ฐ์ ๋ณํ๋ ๊ด์ฐฐํ์ง ๋ชปํจ.
๐ UIViewController+Rx
import Foundation
import RxCocoa
import RxSwift
extension Reactive where Base: UIViewController {
var viewWillAppear: ControlEvent<Void> {
let source = self.methodInvoked(#selector(Base.viewWillAppear(_:))).map { _ in }
return ControlEvent(events: source)
}
}
์ฌ์ฉ๋ฒ์ ์๋์ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
rx.viewWillAppear // UIViewController+Rx์ ์ ์
.asObservable() // ๋ฐํ๋๋ ์ด๋ฒคํธ๋ฅผ ์ต์ ๋ฒ๋ธ ํ์
์ผ๋ก ๋ฐ๋๋ค. (๊ณต์๋ฌธ์ link์ ์ํ๋ฉด From์ผ๋ก ์ฐ๊ฒฐ๋์ด ์์)
.bind(to: viewWillAppearSubject)
.disposed(by: disposeBag)
๐ UIButton+Rx.swift
import Foundation
import RxCocoa
import RxSwift
extension Reactive where Base: UIButton {
// ๊ฐ์ ๊ธฐ๋ฅ์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํ ๋ชฉ์ !
public var customChangeTitle: Binder<String> {
let s = Binder<String>(base) { btn, text in
btn.setTitle(text, for: [])
}
return s
} // ๊ฐ์ ๊ธฐ๋ฅ์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํ ๋ชฉ์ !
}
์ ์๋ ๋ ์ฝ๋๋ target์ด base์์ผ๋ก ๊ฐ์ ๊ธฐ๋ฅ์ ํ๋ค.
extension Reactive where Base: UIButton {
// ๊ฐ์ ๊ธฐ๋ฅ์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํ ๋ชฉ์ !
public var customChangeTitle: Binder<String> {
let s = Binder<String>(base) { _, text in
base.setTitle(text, for: [])
}
return s
}
}
Binder<String>(base, binding: {}) // ํด๋ก์ ๊ตฌ๋ฌธ ์ด๋ ๊ฒ๋ ์์ฑ ๊ฐ๋ฅ
์ด๋ค ์ผ์ ํ ์ ์๋๋ฉด
myButton.rx
.tap
.map{ "text" }
.bind(to: myButton.rx.customChangeTitle)
.disposed(by: bag)
์ด๋ ๊ฒ ํด์ ์ฌ์ฉํ ์ ์์ด. ํจ์๊ฐ ์ฌ๋ผ์ ธ์ ํจ์ฌ ์ข์ ๊ตฌ์กฐ
๐ UITextField+Rx.swift
import Foundation
import RxCocoa
import RxSwift
import UIKit
extension Reactive where Base: UITextField {
public var text: ControlProperty<String?> {
value
}
}
ControlProperty๋ ๊ฐ์ ์ฃผ์ ํ ์ ์๊ธฐ ๋๋ฌธ์
textField.rx.text.onNext("Hello") // ๊ฐ์ ์ฃผ์
ํ ์ ์๊ธฐ ๋๋ฌธ์
textField.rx.text.subcribe(onNext: { _ in }) // ๊ฐ์ ๊ด์ฐฐํ ์ ์๊ธฐ ๋๋ฌธ์
โ Binder์ ์ํ์ ๋ํด์ ์ดํด๋ณด์.
extension์ผ๋ก Binder๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํ๋ ๊ฒฝ์ฐ์๋ target์ ๋ฐ์์ผ ํ๋ค.
๊ทธ๋์ ์๊น Button์์ ๊ฐ์ ๊ธฐ๋ฅ์ ํ๋ ๊ฒ๋ ์ด์ ๊ฐ์ ์ด์ ์์์ด๋ค.
'apple > ๐ฆ UIKit & ReactiveX' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
RxSwift ch 18. Table & Collection views (0) | 2022.01.18 |
---|---|
[iOS] RxDelegateProxy + WebSocket (Starscream) ๐ก (1) | 2022.01.17 |
[iOS] RxDelegateProxy 2ํธ (feat. websocket + objc๊ฐ ์๋ ๊ฒฝ์ฐ) (0) | 2022.01.12 |
[iOS] RxDelegateProxy 1ํธ (feat. example) (0) | 2022.01.12 |
[iOS] starscream ์ฌ์ฉ๋ฒ ์ด์ ๋ฆฌ! (0) | 2022.01.12 |