- Update: Migrate from Variable to BehaviorRelay.
- Fix: PaginationWrapper retry load more after fail. - Fix: safeClear method of TableDirector now creates section without header and footer. - Add: TableSection convenience initializer.
This commit is contained in:
parent
bb7fe4f7f2
commit
7249bf66dc
|
|
@ -1,5 +1,11 @@
|
|||
# Changelog
|
||||
|
||||
### 0.7.13
|
||||
- **Update**: Migrate from `Variable` to `BehaviorRelay`.
|
||||
- **Fix**: `PaginationWrapper` retry load more after fail.
|
||||
- **Fix**: `safeClear` method of `TableDirector` now creates section without header and footer.
|
||||
- **Add**: `TableSection` convenience initializer for section without footer and header.
|
||||
|
||||
### 0.7.12
|
||||
- **Add**: `UniversalMappable` protocol to have ability generate generic mapping models
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ Pod::Spec.new do |s|
|
|||
"Sources/Extensions/DataLoading/GeneralDataLoading/GeneralDataLoadingController+DefaultImplementation.swift",
|
||||
"Sources/Extensions/DataLoading/PaginationDataLoading/*",
|
||||
"Sources/Extensions/Support/UIScrollView+Support.swift",
|
||||
"Sources/Extensions/TableDirector/*",
|
||||
"Sources/Extensions/TableKit/**/*.swift",
|
||||
"Sources/Extensions/Array/Array+SeparatorRowBoxExtensions.swift",
|
||||
"Sources/Extensions/Drawing/UIImage/*",
|
||||
"Sources/Extensions/UIKit/**/*.swift",
|
||||
|
|
@ -65,7 +65,7 @@ Pod::Spec.new do |s|
|
|||
"Sources/Extensions/NetworkService/NetworkService+ActivityIndicator-UIApplication.swift",
|
||||
"Sources/Extensions/DataLoading/PaginationDataLoading/*",
|
||||
"Sources/Extensions/Support/UIScrollView+Support.swift",
|
||||
"Sources/Extensions/TableDirector/*",
|
||||
"Sources/Extensions/TableKit/**/*.swift",
|
||||
"Sources/Extensions/UIKit/UIApplication/UIApplication+OpenUrlSupport.swift",
|
||||
"Sources/Extensions/UIKit/UIApplication/UIApplication+Cellular.swift",
|
||||
"Sources/Extensions/Array/Array+SeparatorRowBoxExtensions.swift",
|
||||
|
|
@ -97,7 +97,7 @@ Pod::Spec.new do |s|
|
|||
"Sources/Classes/DataLoading/PaginationDataLoading/PaginationWrapper.swift",
|
||||
"Sources/Extensions/NetworkService/NetworkService+ActivityIndicator-UIApplication.swift",
|
||||
"Sources/Extensions/DataLoading/PaginationDataLoading/*",
|
||||
"Sources/Extensions/TableDirector/*",
|
||||
"Sources/Extensions/TableKit/**/*.swift",
|
||||
"Sources/Extensions/UIApplication/UIApplication+OpenUrlSupport.swift",
|
||||
"Sources/Extensions/UIApplication/UIApplication+Cellular.swift",
|
||||
"Sources/Extensions/Array/Array+SeparatorRowBoxExtensions.swift",
|
||||
|
|
|
|||
|
|
@ -347,6 +347,8 @@
|
|||
675C1FB41F97CA32007D5249 /* AppearanceConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */; };
|
||||
675C1FB51F97CA33007D5249 /* AppearanceConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */; };
|
||||
675C1FB61F97CA33007D5249 /* AppearanceConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */; };
|
||||
6762131820A0BBA30034EEF1 /* TableSection+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6762131720A0BBA30034EEF1 /* TableSection+Extensions.swift */; };
|
||||
6762131920A0BBA30034EEF1 /* TableSection+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6762131720A0BBA30034EEF1 /* TableSection+Extensions.swift */; };
|
||||
676B22A2206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */; };
|
||||
676B22A3206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */; };
|
||||
676B22A4206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */; };
|
||||
|
|
@ -710,6 +712,7 @@
|
|||
673CF4332063E29B00C329F6 /* TextWithButtonPlaceholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextWithButtonPlaceholder.swift; sourceTree = "<group>"; };
|
||||
673CF4372063E7CE00C329F6 /* GeneralDataLoadingController+DefaultImplementation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GeneralDataLoadingController+DefaultImplementation.swift"; sourceTree = "<group>"; };
|
||||
674AF55B1EC45B1600038A8F /* UIActivityIndicatorView+LoadingIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIActivityIndicatorView+LoadingIndicator.swift"; sourceTree = "<group>"; };
|
||||
6762131720A0BBA30034EEF1 /* TableSection+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TableSection+Extensions.swift"; sourceTree = "<group>"; };
|
||||
676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Extensions.swift"; sourceTree = "<group>"; };
|
||||
6771DFE91EEA7CB8002DCDAE /* DateFormattingService+MappingTransform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DateFormattingService+MappingTransform.swift"; sourceTree = "<group>"; };
|
||||
67745267206249360024EEEF /* UITableView+PaginationWrappable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+PaginationWrappable.swift"; sourceTree = "<group>"; };
|
||||
|
|
@ -957,7 +960,7 @@
|
|||
82F8BB161F5DDED100C1061B /* Single */,
|
||||
671461FA1EB3396E00EAB194 /* String */,
|
||||
671461FE1EB3396E00EAB194 /* Support */,
|
||||
671462001EB3396E00EAB194 /* TableDirector */,
|
||||
6762131520A0BAD40034EEF1 /* TableKit */,
|
||||
671462021EB3396E00EAB194 /* TimeInterval */,
|
||||
671462081EB3396E00EAB194 /* UIColor */,
|
||||
672947E0206EA36B00AC6B6B /* UIKit */,
|
||||
|
|
@ -1425,6 +1428,23 @@
|
|||
path = UIActivityIndicatorView;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6762131520A0BAD40034EEF1 /* TableKit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6762131620A0BAF70034EEF1 /* TableSection */,
|
||||
671462001EB3396E00EAB194 /* TableDirector */,
|
||||
);
|
||||
path = TableKit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6762131620A0BAF70034EEF1 /* TableSection */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6762131720A0BBA30034EEF1 /* TableSection+Extensions.swift */,
|
||||
);
|
||||
path = TableSection;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
676B22A0206A6249002E9F8A /* NSAttributedString */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -2633,6 +2653,7 @@
|
|||
A676AE551F98112E001F9214 /* ObservableMappable.swift in Sources */,
|
||||
A6E0DDE11F8A696F002CA74E /* SeparatorRowBox.swift in Sources */,
|
||||
A6E0DDDE1F8A696F002CA74E /* EmptyCellRow.swift in Sources */,
|
||||
6762131820A0BBA30034EEF1 /* TableSection+Extensions.swift in Sources */,
|
||||
67EB7FFD206176C900BDD9FB /* AnyPaginationWrappable.swift in Sources */,
|
||||
671463041EB3396E00EAB194 /* UIView+LoadingIndicator.swift in Sources */,
|
||||
6774527420624E820024EEEF /* DataLoadingModel.swift in Sources */,
|
||||
|
|
@ -2971,6 +2992,7 @@
|
|||
676B22A5206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */,
|
||||
673CF4142063ABD100C329F6 /* GeneralDataLoadingState+Extensions.swift in Sources */,
|
||||
671462DB1EB3396E00EAB194 /* TimeInterval+DateComponents.swift in Sources */,
|
||||
6762131920A0BBA30034EEF1 /* TableSection+Extensions.swift in Sources */,
|
||||
6774529020625C9E0024EEEF /* GeneralDataLoadingState.swift in Sources */,
|
||||
67EB7FC3206140E600BDD9FB /* TotalCountCursor.swift in Sources */,
|
||||
EF24213D2076D5CA00FA9BE6 /* NetworkServiceConfiguration.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
PODS:
|
||||
- Alamofire (4.7.1)
|
||||
- Alamofire (4.7.2)
|
||||
- ObjectMapper (3.1.0)
|
||||
- RxAlamofire (4.2.0):
|
||||
- RxAlamofire/Core (= 4.2.0)
|
||||
|
|
@ -10,7 +10,7 @@ PODS:
|
|||
- RxSwift (~> 4.0)
|
||||
- RxSwift (4.1.2)
|
||||
- SwiftDate (4.5.1)
|
||||
- SwiftLint (0.25.0)
|
||||
- SwiftLint (0.25.1)
|
||||
- TableKit (2.6.0)
|
||||
- UIScrollView-InfiniteScroll (1.0.2)
|
||||
|
||||
|
|
@ -25,13 +25,13 @@ DEPENDENCIES:
|
|||
- UIScrollView-InfiniteScroll (~> 1.0.0)
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Alamofire: 68d7d521118d49c615a8d2214d87cdf525599d30
|
||||
Alamofire: e4fa87002c137ba2d8d634d2c51fabcda0d5c223
|
||||
ObjectMapper: 20505058f54e5c3ca69e1d6de9897d152a5369a6
|
||||
RxAlamofire: 87a9c588541210cc3e4a1f843ccc3ecf3eb98b31
|
||||
RxCocoa: d88ba0f1f6abf040011a9eb4b539324fc426843a
|
||||
RxSwift: e49536837d9901277638493ea537394d4b55f570
|
||||
SwiftDate: 7b56d42a221f582047287deb256b23fc5ed49a60
|
||||
SwiftLint: e14651157288e9e01d6e1a71db7014fb5744a8ea
|
||||
SwiftLint: ce933681be10c3266e82576dad676fa815a602e9
|
||||
TableKit: 61880e4c13ac0ba396a308fcb1ae48f6dec8b458
|
||||
UIScrollView-InfiniteScroll: c132d6d5851daff229ab4a1060ccf70a05a051c9
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ open class GeneralDataLoadingViewModel<ResultType>: BaseViewModel {
|
|||
|
||||
private let loadingModel: LoadingModel
|
||||
|
||||
private let loadingStateVariable = Variable<LoadingState>(.initial)
|
||||
private let loadingStateRelay = BehaviorRelay<LoadingState>(value: .initial)
|
||||
|
||||
public let disposeBag = DisposeBag()
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ open class GeneralDataLoadingViewModel<ResultType>: BaseViewModel {
|
|||
loadingModel = LoadingModel(dataSource: dataSource, emptyResultChecker: emptyResultChecker)
|
||||
|
||||
loadingModel.stateDriver
|
||||
.drive(loadingStateVariable)
|
||||
.drive(loadingStateRelay)
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
loadingModel.reload()
|
||||
|
|
@ -54,7 +54,7 @@ open class GeneralDataLoadingViewModel<ResultType>: BaseViewModel {
|
|||
|
||||
/// Returns driver that emits current loading state
|
||||
open var loadingStateDriver: Driver<LoadingState> {
|
||||
return loadingStateVariable.asDriver()
|
||||
return loadingStateRelay.asDriver()
|
||||
}
|
||||
|
||||
/// By default returns true if loading state == .result.
|
||||
|
|
@ -70,10 +70,10 @@ open class GeneralDataLoadingViewModel<ResultType>: BaseViewModel {
|
|||
/// Current state of loading process.
|
||||
private(set) public var currentLoadingState: LoadingState {
|
||||
get {
|
||||
return loadingStateVariable.value
|
||||
return loadingStateRelay.value
|
||||
}
|
||||
set {
|
||||
loadingStateVariable.value = newValue
|
||||
loadingStateRelay.accept(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ final public class PaginationWrapper<Cursor: ResettableRxDataSourceCursor, Deleg
|
|||
private var currentPlaceholderView: UIView?
|
||||
private var currentPlaceholderViewTopConstraint: NSLayoutConstraint?
|
||||
|
||||
private let applicationCurrentyActive = Variable<Bool>(true)
|
||||
private let applicationCurrentyActive = BehaviorRelay(value: true)
|
||||
|
||||
/// Initializer with table view, placeholders container view, cusor and delegate parameters.
|
||||
///
|
||||
|
|
@ -193,7 +193,7 @@ final public class PaginationWrapper<Cursor: ResettableRxDataSourceCursor, Deleg
|
|||
retryButton.rx
|
||||
.controlEvent(.touchUpInside)
|
||||
.asDriver()
|
||||
.drive(reloadEvent)
|
||||
.drive(retryEvent)
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
delegate?.footerRetryButtonWillAppear()
|
||||
|
|
@ -350,13 +350,13 @@ private extension PaginationWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
var retryEvent: Binder<()> {
|
||||
var retryEvent: Binder<Void> {
|
||||
return Binder(self) { base, _ in
|
||||
base.paginationViewModel.loadMore()
|
||||
}
|
||||
}
|
||||
|
||||
var reloadEvent: Binder<()> {
|
||||
var reloadEvent: Binder<Void> {
|
||||
return Binder(self) { base, _ in
|
||||
base.reload()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,14 +31,14 @@ open class RxDataLoadingModel<LoadingStateType: DataLoadingState>: DataLoadingMo
|
|||
|
||||
public typealias EmptyResultChecker = (ResultType) -> Bool
|
||||
|
||||
private let stateVariable = Variable<LoadingStateType>(.initialState)
|
||||
private let stateRelay = BehaviorRelay<LoadingStateType>(value: .initialState)
|
||||
var currentRequestDisposable: Disposable?
|
||||
|
||||
var dataSource: DataSourceType
|
||||
let emptyResultChecker: EmptyResultChecker
|
||||
|
||||
open var stateDriver: Driver<LoadingStateType> {
|
||||
return stateVariable.asDriver()
|
||||
return stateRelay.asDriver()
|
||||
}
|
||||
|
||||
public init(dataSource: DataSourceType, emptyResultChecker: @escaping EmptyResultChecker) {
|
||||
|
|
@ -86,10 +86,10 @@ open class RxDataLoadingModel<LoadingStateType: DataLoadingState>: DataLoadingMo
|
|||
|
||||
var state: LoadingStateType {
|
||||
get {
|
||||
return stateVariable.value
|
||||
return stateRelay.value
|
||||
}
|
||||
set {
|
||||
stateVariable.value = newValue
|
||||
stateRelay.accept(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,17 +30,17 @@ import RxAlamofire
|
|||
/// Has an ability to automatically show / hide network activity indicator
|
||||
open class NetworkService {
|
||||
|
||||
/// Enable synchronization for setting variable from different thread
|
||||
/// Enable synchronization for setting behaviour relay from different thread
|
||||
private let lock = NSRecursiveLock()
|
||||
|
||||
private let requestCountVariable = Variable<Int>(0)
|
||||
private let requestCountRelay = BehaviorRelay(value: 0)
|
||||
private var disposeBag = DisposeBag()
|
||||
|
||||
public let configuration: NetworkServiceConfiguration
|
||||
public let sessionManager: Alamofire.SessionManager
|
||||
|
||||
var requestCount: Driver<Int> {
|
||||
return requestCountVariable.asDriver()
|
||||
return requestCountRelay.asDriver()
|
||||
}
|
||||
|
||||
/// - Parameter sessionManager: Alamofire.SessionManager to use for requests
|
||||
|
|
@ -98,13 +98,13 @@ private extension NetworkService {
|
|||
|
||||
func increaseRequestCounter() {
|
||||
lock.lock()
|
||||
requestCountVariable.value += 1
|
||||
requestCountRelay.accept(requestCountRelay.value + 1)
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
func decreaseRequestCounter() {
|
||||
lock.lock()
|
||||
requestCountVariable.value -= 1
|
||||
requestCountRelay.accept(requestCountRelay.value - 1)
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ internal final class TextWithButtonPlaceholder: UIView {
|
|||
stackView.axis = .vertical
|
||||
|
||||
addSubview(stackView)
|
||||
|
||||
stackView.setToCenter(withSize: nil)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public final class DataModelFieldBinding<T> {
|
|||
public typealias GetFieldClosure = (T) -> String?
|
||||
public typealias MergeFieldClosure = (T, String?) -> T
|
||||
|
||||
private let modelVariable: Variable<T>
|
||||
private let modelRelay: BehaviorRelay<T>
|
||||
private let modelDriver: Driver<T>
|
||||
private let getFieldClosure: DataModelFieldBinding<T>.GetFieldClosure
|
||||
private let mergeFieldClosure: DataModelFieldBinding<T>.MergeFieldClosure
|
||||
|
|
@ -37,16 +37,16 @@ public final class DataModelFieldBinding<T> {
|
|||
/// Memberwise initializer.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - modelVariable: Variable that contains data model.
|
||||
/// - modelRelay: BehaviourRelay that contains data model.
|
||||
/// - modelDriver: Driver that emits new data models.
|
||||
/// - getFieldClosure: Closure for getting field string reprerentation from data model.
|
||||
/// - mergeFieldClosure: Closure for merging new field value into data model.
|
||||
public init(modelVariable: Variable<T>,
|
||||
public init(modelRelay: BehaviorRelay<T>,
|
||||
modelDriver: Driver<T>,
|
||||
getFieldClosure: @escaping GetFieldClosure,
|
||||
mergeFieldClosure: @escaping MergeFieldClosure) {
|
||||
|
||||
self.modelVariable = modelVariable
|
||||
self.modelRelay = modelRelay
|
||||
self.modelDriver = modelDriver
|
||||
self.getFieldClosure = getFieldClosure
|
||||
self.mergeFieldClosure = mergeFieldClosure
|
||||
|
|
@ -55,12 +55,12 @@ public final class DataModelFieldBinding<T> {
|
|||
/// Method that merges new field values with data model.
|
||||
///
|
||||
/// - Parameter textDriver: Driver that emits new text values.
|
||||
/// - Returns: Disposable object that can be used to unsubscribe the observer from the variable.
|
||||
/// - Returns: Disposable object that can be used to unsubscribe the observer from the behaviour relay.
|
||||
public func mergeStringToModel(from textDriver: Driver<String?>) -> Disposable {
|
||||
return textDriver.map { [modelVariable, mergeFieldClosure] in
|
||||
mergeFieldClosure(modelVariable.value, $0)
|
||||
return textDriver.map { [modelRelay, mergeFieldClosure] in
|
||||
mergeFieldClosure(modelRelay.value, $0)
|
||||
}
|
||||
.drive(modelVariable)
|
||||
.drive(modelRelay)
|
||||
}
|
||||
|
||||
/// A Driver that will emit current field value.
|
||||
|
|
@ -72,18 +72,18 @@ public final class DataModelFieldBinding<T> {
|
|||
|
||||
public extension DataModelFieldBinding {
|
||||
|
||||
/// Convenience initializer without modelDriver, which will be obtained from modelVariable.
|
||||
/// Convenience initializer without modelDriver, which will be obtained from modelRelay.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - modelVariable: Variable that contains data model.
|
||||
/// - modelRelay: BehaviourRelay that contains data model.
|
||||
/// - getFieldClosure: Closure for getting field string reprerentation from data model.
|
||||
/// - mergeFieldClosure: Closure for merging new field value into data model.
|
||||
convenience init(modelVariable: Variable<T>,
|
||||
convenience init(modelRelay: BehaviorRelay<T>,
|
||||
getFieldClosure: @escaping GetFieldClosure,
|
||||
mergeFieldClosure: @escaping MergeFieldClosure) {
|
||||
|
||||
self.init(modelVariable: modelVariable,
|
||||
modelDriver: modelVariable.asDriver(),
|
||||
self.init(modelRelay: modelRelay,
|
||||
modelDriver: modelRelay.asDriver(),
|
||||
getFieldClosure: getFieldClosure,
|
||||
mergeFieldClosure: mergeFieldClosure)
|
||||
}
|
||||
|
|
@ -94,19 +94,19 @@ public extension DataModelFieldBinding where T == String? {
|
|||
|
||||
/// Convenience initializer for data model of string.
|
||||
///
|
||||
/// - Parameter modelVariable: Variable that contains data model.
|
||||
convenience init(modelVariable: Variable<T>) {
|
||||
self.init(modelVariable: modelVariable,
|
||||
modelDriver: modelVariable.asDriver(),
|
||||
/// - Parameter modelRelay: BehaviourRelay that contains data model.
|
||||
convenience init(modelRelay: BehaviorRelay<T>) {
|
||||
self.init(modelRelay: modelRelay,
|
||||
modelDriver: modelRelay.asDriver(),
|
||||
getFieldClosure: { $0 },
|
||||
mergeFieldClosure: { $1 })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public extension Variable {
|
||||
public extension BehaviorRelay {
|
||||
|
||||
/// Creates DataModelFieldBinding configured with given closures and variable itself.
|
||||
/// Creates DataModelFieldBinding configured with given closures and behaviour relay itself.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - getFieldClosure: Closure for getting field string reprerentation from data model.
|
||||
|
|
@ -115,20 +115,20 @@ public extension Variable {
|
|||
func fieldBinding(getFieldClosure: @escaping DataModelFieldBinding<E>.GetFieldClosure,
|
||||
mergeFieldClosure: @escaping DataModelFieldBinding<E>.MergeFieldClosure) -> DataModelFieldBinding<E> {
|
||||
|
||||
return DataModelFieldBinding(modelVariable: self,
|
||||
return DataModelFieldBinding(modelRelay: self,
|
||||
getFieldClosure: getFieldClosure,
|
||||
mergeFieldClosure: mergeFieldClosure)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public extension Variable where Element == String? {
|
||||
public extension BehaviorRelay where Element == String? {
|
||||
|
||||
/// Creates DataModelFieldBinding configured with variable itself.
|
||||
/// Creates DataModelFieldBinding configured with behaviour relay itself.
|
||||
///
|
||||
/// - Returns: DataModelFieldBinding instance.
|
||||
func fieldBinding() -> DataModelFieldBinding<E> {
|
||||
return DataModelFieldBinding(modelVariable: self)
|
||||
return DataModelFieldBinding(modelRelay: self)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ open class TextFieldViewModel<ViewEvents: TextFieldViewEvents,
|
|||
/// Events that can be emitted by view model.
|
||||
public let viewModelEvents: ViewModelEvents
|
||||
|
||||
private let viewEventsVariable = Variable<ViewEvents?>(nil)
|
||||
private let viewEventsRelay = BehaviorRelay<ViewEvents?>(value: nil)
|
||||
|
||||
private(set) public var disposeBag = DisposeBag()
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ open class TextFieldViewModel<ViewEvents: TextFieldViewEvents,
|
|||
/// View events driver that will emit view events structure
|
||||
/// when view will bind itself to the view model.
|
||||
public var viewEventsDriver: Driver<ViewEvents> {
|
||||
return viewEventsVariable
|
||||
return viewEventsRelay
|
||||
.asDriver()
|
||||
.flatMap { viewEvents -> Driver<ViewEvents> in
|
||||
guard let viewEvents = viewEvents else {
|
||||
|
|
@ -59,7 +59,7 @@ open class TextFieldViewModel<ViewEvents: TextFieldViewEvents,
|
|||
///
|
||||
/// - Parameter viewEvents: View events structure.
|
||||
public func bind(viewEvents: ViewEvents) {
|
||||
viewEventsVariable.value = viewEvents
|
||||
viewEventsRelay.accept(viewEvents)
|
||||
}
|
||||
|
||||
/// Unbinds view from view model.
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ public extension TableDirector {
|
|||
|
||||
/// Clear table view and reload it within empty section
|
||||
func safeClear() {
|
||||
clear().append(section: TableSection()).reload()
|
||||
clear().append(section: TableSection(onlyRows: [])).reload()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import TableKit
|
||||
|
||||
public extension TableSection {
|
||||
|
||||
/// Initializes section with rows and zero height footer and header.
|
||||
///
|
||||
/// - Parameter rows: Rows to insert into section.
|
||||
convenience init(onlyRows rows: [Row]) {
|
||||
self.init(rows: rows)
|
||||
|
||||
self.headerView = nil
|
||||
self.footerView = nil
|
||||
|
||||
self.headerHeight = .leastNonzeroMagnitude
|
||||
self.footerHeight = .leastNonzeroMagnitude
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
import RxCocoa
|
||||
|
||||
/// Protocol that describes data loading process
|
||||
/// with methods reload & retry and current state driver variable.
|
||||
/// with methods reload & retry and current state driver.
|
||||
public protocol DataLoadingModel {
|
||||
|
||||
associatedtype LoadingStateType: DataLoadingState
|
||||
|
|
|
|||
Loading…
Reference in New Issue