Simplifies data sources and delegates.

This commit is contained in:
Krunoslav Zaher 2015-07-04 13:22:05 +02:00
parent ede99d27d1
commit 1f6df23810
51 changed files with 712 additions and 2407 deletions

View File

@ -18,12 +18,11 @@
C83225471B1A9CCB0048EC77 /* UIDatePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83225461B1A9CCB0048EC77 /* UIDatePicker.swift */; };
C83225491B1A9ECC0048EC77 /* NSControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83225481B1A9ECC0048EC77 /* NSControl+Rx.swift */; };
C83CF8631B3DDD54001359E7 /* RxTableViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83CF8621B3DDD54001359E7 /* RxTableViewReactiveArrayDataSource.swift */; };
C83CF8771B3DE811001359E7 /* RxScrollViewDelegateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83CF8761B3DE811001359E7 /* RxScrollViewDelegateType.swift */; };
C83CF8791B3DE923001359E7 /* RxTableViewDelegateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83CF8781B3DE923001359E7 /* RxTableViewDelegateType.swift */; };
C83CF87B1B3DFDF8001359E7 /* RxScrollViewDelegateConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83CF87A1B3DFDF8001359E7 /* RxScrollViewDelegateConverter.swift */; };
C83CF87D1B3E0316001359E7 /* RxScrollViewNopDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83CF87C1B3E0316001359E7 /* RxScrollViewNopDelegate.swift */; };
C83CF87F1B3E0A25001359E7 /* RxTableViewDelegateConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83CF87E1B3E0A25001359E7 /* RxTableViewDelegateConverter.swift */; };
C83CF8811B3E0B9D001359E7 /* RxTableViewNopDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C83CF8801B3E0B9D001359E7 /* RxTableViewNopDelegate.swift */; };
C84969CA1B47DE1D00E0BDB9 /* RxCollectionViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84969C51B47DE1D00E0BDB9 /* RxCollectionViewDataSourceProxy.swift */; };
C84969CB1B47DE1D00E0BDB9 /* RxCollectionViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84969C61B47DE1D00E0BDB9 /* RxCollectionViewDelegateProxy.swift */; };
C84969CC1B47DE1D00E0BDB9 /* RxScrollViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84969C71B47DE1D00E0BDB9 /* RxScrollViewDelegateProxy.swift */; };
C84969CD1B47DE1D00E0BDB9 /* RxTableViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84969C81B47DE1D00E0BDB9 /* RxTableViewDataSourceProxy.swift */; };
C84969CE1B47DE1D00E0BDB9 /* RxTableViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84969C91B47DE1D00E0BDB9 /* RxTableViewDelegateProxy.swift */; };
C86282391B36037100500DC3 /* ControlTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86282321B36037100500DC3 /* ControlTarget.swift */; };
C862823A1B36037100500DC3 /* ControlTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86282321B36037100500DC3 /* ControlTarget.swift */; };
C862823B1B36037100500DC3 /* KVOObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86282331B36037100500DC3 /* KVOObservable.swift */; };
@ -59,33 +58,13 @@
C88BB8EE1B07F2BE0064D411 /* UITableView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88BB8E61B07F2BE0064D411 /* UITableView+Rx.swift */; };
C88BB8EF1B07F2BE0064D411 /* UITextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88BB8E71B07F2BE0064D411 /* UITextField+Rx.swift */; };
C88BB91D1B07FD960064D411 /* NSButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88BB91B1B07FD830064D411 /* NSButton+Rx.swift */; };
C88C788C1B3EBA050061C5AB /* DelegateConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88C788B1B3EBA050061C5AB /* DelegateConverterType.swift */; };
C88C788D1B3EBA050061C5AB /* DelegateConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88C788B1B3EBA050061C5AB /* DelegateConverterType.swift */; };
C8A56BCE1AD744FD00B4673B /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8A56BCD1AD744FD00B4673B /* RxSwift.framework */; };
C8A57F761B4141CC00D5570A /* RxCollectionViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F751B4141CC00D5570A /* RxCollectionViewDataSourceType.swift */; };
C8A57F781B41424800D5570A /* RxCollectionViewDelegateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F771B41424800D5570A /* RxCollectionViewDelegateType.swift */; };
C8A57F7A1B41431600D5570A /* RxCollectionViewReactiveDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F791B41431600D5570A /* RxCollectionViewReactiveDataSourceType.swift */; };
C8A57F7C1B41438700D5570A /* RxCollectionViewDataSourceBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F7B1B41438700D5570A /* RxCollectionViewDataSourceBridge.swift */; };
C8A57F7E1B41464C00D5570A /* RxCollectionViewNopDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F7D1B41464C00D5570A /* RxCollectionViewNopDelegate.swift */; };
C8A57F801B41478A00D5570A /* RxCollectionViewDelegateBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F7F1B41478A00D5570A /* RxCollectionViewDelegateBridge.swift */; };
C8A57F821B41479A00D5570A /* RxCollectionViewDelegateConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F811B41479A00D5570A /* RxCollectionViewDelegateConverter.swift */; };
C8A57F841B41514E00D5570A /* RxCollectionViewNopDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F831B41514E00D5570A /* RxCollectionViewNopDataSource.swift */; };
C8A57F861B41520C00D5570A /* RxCollectionViewDataSourceConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F851B41520C00D5570A /* RxCollectionViewDataSourceConverter.swift */; };
C8A57F7A1B41431600D5570A /* RxCollectionViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F791B41431600D5570A /* RxCollectionViewDataSourceType.swift */; };
C8A57F881B41530A00D5570A /* RxCollectionViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F871B41530A00D5570A /* RxCollectionViewReactiveArrayDataSource.swift */; };
C8AED7C41B3C91B700678DDE /* RxScrollViewDelegateBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7BC1B3C91B700678DDE /* RxScrollViewDelegateBridge.swift */; };
C8AED7C51B3C91B700678DDE /* RxScrollViewDelegateBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7BC1B3C91B700678DDE /* RxScrollViewDelegateBridge.swift */; };
C8AED7C81B3C91B700678DDE /* RxTableViewDataSourceBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7BE1B3C91B700678DDE /* RxTableViewDataSourceBridge.swift */; };
C8AED7C91B3C91B700678DDE /* RxTableViewDataSourceBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7BE1B3C91B700678DDE /* RxTableViewDataSourceBridge.swift */; };
C8AED7CC1B3C91B700678DDE /* RxTableViewDelegateBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7C01B3C91B700678DDE /* RxTableViewDelegateBridge.swift */; };
C8AED7CD1B3C91B700678DDE /* RxTableViewDelegateBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7C01B3C91B700678DDE /* RxTableViewDelegateBridge.swift */; };
C8AED7D91B3CAA4F00678DDE /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7D81B3CAA4F00678DDE /* RxTableViewDataSourceType.swift */; };
C8AED7DA1B3CAA4F00678DDE /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7D81B3CAA4F00678DDE /* RxTableViewDataSourceType.swift */; };
C8AED7E61B3CC60300678DDE /* RxTableViewNopDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7E51B3CC60300678DDE /* RxTableViewNopDataSource.swift */; };
C8AED7E91B3CC93600678DDE /* RxTableViewReactiveDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7E81B3CC93600678DDE /* RxTableViewReactiveDataSourceType.swift */; };
C8AED7EA1B3CC93600678DDE /* RxTableViewReactiveDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7E81B3CC93600678DDE /* RxTableViewReactiveDataSourceType.swift */; };
C8AED7EC1B3D4F3700678DDE /* RxTableViewDataSourceConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7EB1B3D4F3700678DDE /* RxTableViewDataSourceConverter.swift */; };
C8D95C171B2F0CD700FA661F /* DelegateBridgeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D95C161B2F0CD700FA661F /* DelegateBridgeType.swift */; };
C8D95C181B2F0CD700FA661F /* DelegateBridgeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D95C161B2F0CD700FA661F /* DelegateBridgeType.swift */; };
C8AED7E91B3CC93600678DDE /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7E81B3CC93600678DDE /* RxTableViewDataSourceType.swift */; };
C8AED7EA1B3CC93600678DDE /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AED7E81B3CC93600678DDE /* RxTableViewDataSourceType.swift */; };
C8D95C171B2F0CD700FA661F /* DelegateProxyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D95C161B2F0CD700FA661F /* DelegateProxyType.swift */; };
C8D95C181B2F0CD700FA661F /* DelegateProxyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D95C161B2F0CD700FA661F /* DelegateProxyType.swift */; };
CBEEA67A1B12364200176529 /* NSSlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBEEA6781B12323800176529 /* NSSlider+Rx.swift */; };
/* End PBXBuildFile section */
@ -102,12 +81,11 @@
C83225461B1A9CCB0048EC77 /* UIDatePicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIDatePicker.swift; sourceTree = "<group>"; };
C83225481B1A9ECC0048EC77 /* NSControl+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSControl+Rx.swift"; sourceTree = "<group>"; };
C83CF8621B3DDD54001359E7 /* RxTableViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewReactiveArrayDataSource.swift; sourceTree = "<group>"; };
C83CF8761B3DE811001359E7 /* RxScrollViewDelegateType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxScrollViewDelegateType.swift; sourceTree = "<group>"; };
C83CF8781B3DE923001359E7 /* RxTableViewDelegateType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDelegateType.swift; sourceTree = "<group>"; };
C83CF87A1B3DFDF8001359E7 /* RxScrollViewDelegateConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxScrollViewDelegateConverter.swift; sourceTree = "<group>"; };
C83CF87C1B3E0316001359E7 /* RxScrollViewNopDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxScrollViewNopDelegate.swift; sourceTree = "<group>"; };
C83CF87E1B3E0A25001359E7 /* RxTableViewDelegateConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDelegateConverter.swift; sourceTree = "<group>"; };
C83CF8801B3E0B9D001359E7 /* RxTableViewNopDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewNopDelegate.swift; sourceTree = "<group>"; };
C84969C51B47DE1D00E0BDB9 /* RxCollectionViewDataSourceProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDataSourceProxy.swift; sourceTree = "<group>"; };
C84969C61B47DE1D00E0BDB9 /* RxCollectionViewDelegateProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDelegateProxy.swift; sourceTree = "<group>"; };
C84969C71B47DE1D00E0BDB9 /* RxScrollViewDelegateProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxScrollViewDelegateProxy.swift; sourceTree = "<group>"; };
C84969C81B47DE1D00E0BDB9 /* RxTableViewDataSourceProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDataSourceProxy.swift; sourceTree = "<group>"; };
C84969C91B47DE1D00E0BDB9 /* RxTableViewDelegateProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDelegateProxy.swift; sourceTree = "<group>"; };
C86282321B36037100500DC3 /* ControlTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlTarget.swift; sourceTree = "<group>"; };
C86282331B36037100500DC3 /* KVOObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KVOObservable.swift; sourceTree = "<group>"; };
C86282341B36037100500DC3 /* NSNotificationCenter+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSNotificationCenter+Rx.swift"; sourceTree = "<group>"; };
@ -131,26 +109,11 @@
C88BB8E61B07F2BE0064D411 /* UITableView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+Rx.swift"; sourceTree = "<group>"; };
C88BB8E71B07F2BE0064D411 /* UITextField+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextField+Rx.swift"; sourceTree = "<group>"; };
C88BB91B1B07FD830064D411 /* NSButton+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSButton+Rx.swift"; sourceTree = "<group>"; };
C88C788B1B3EBA050061C5AB /* DelegateConverterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelegateConverterType.swift; sourceTree = "<group>"; };
C8A56BCD1AD744FD00B4673B /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C8A57F751B4141CC00D5570A /* RxCollectionViewDataSourceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDataSourceType.swift; sourceTree = "<group>"; };
C8A57F771B41424800D5570A /* RxCollectionViewDelegateType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDelegateType.swift; sourceTree = "<group>"; };
C8A57F791B41431600D5570A /* RxCollectionViewReactiveDataSourceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewReactiveDataSourceType.swift; sourceTree = "<group>"; };
C8A57F7B1B41438700D5570A /* RxCollectionViewDataSourceBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDataSourceBridge.swift; sourceTree = "<group>"; };
C8A57F7D1B41464C00D5570A /* RxCollectionViewNopDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewNopDelegate.swift; sourceTree = "<group>"; };
C8A57F7F1B41478A00D5570A /* RxCollectionViewDelegateBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDelegateBridge.swift; sourceTree = "<group>"; };
C8A57F811B41479A00D5570A /* RxCollectionViewDelegateConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDelegateConverter.swift; sourceTree = "<group>"; };
C8A57F831B41514E00D5570A /* RxCollectionViewNopDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewNopDataSource.swift; sourceTree = "<group>"; };
C8A57F851B41520C00D5570A /* RxCollectionViewDataSourceConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDataSourceConverter.swift; sourceTree = "<group>"; };
C8A57F791B41431600D5570A /* RxCollectionViewDataSourceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDataSourceType.swift; sourceTree = "<group>"; };
C8A57F871B41530A00D5570A /* RxCollectionViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewReactiveArrayDataSource.swift; sourceTree = "<group>"; };
C8AED7BC1B3C91B700678DDE /* RxScrollViewDelegateBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxScrollViewDelegateBridge.swift; sourceTree = "<group>"; };
C8AED7BE1B3C91B700678DDE /* RxTableViewDataSourceBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDataSourceBridge.swift; sourceTree = "<group>"; };
C8AED7C01B3C91B700678DDE /* RxTableViewDelegateBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDelegateBridge.swift; sourceTree = "<group>"; };
C8AED7D81B3CAA4F00678DDE /* RxTableViewDataSourceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDataSourceType.swift; sourceTree = "<group>"; };
C8AED7E51B3CC60300678DDE /* RxTableViewNopDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewNopDataSource.swift; sourceTree = "<group>"; };
C8AED7E81B3CC93600678DDE /* RxTableViewReactiveDataSourceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewReactiveDataSourceType.swift; sourceTree = "<group>"; };
C8AED7EB1B3D4F3700678DDE /* RxTableViewDataSourceConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDataSourceConverter.swift; sourceTree = "<group>"; };
C8D95C161B2F0CD700FA661F /* DelegateBridgeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelegateBridgeType.swift; sourceTree = "<group>"; };
C8AED7E81B3CC93600678DDE /* RxTableViewDataSourceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewDataSourceType.swift; sourceTree = "<group>"; };
C8D95C161B2F0CD700FA661F /* DelegateProxyType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelegateProxyType.swift; sourceTree = "<group>"; };
CBEEA6781B12323800176529 /* NSSlider+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSSlider+Rx.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -223,6 +186,18 @@
name = "Supporting Files";
sourceTree = "<group>";
};
C84969C41B47DE1D00E0BDB9 /* Proxies */ = {
isa = PBXGroup;
children = (
C84969C51B47DE1D00E0BDB9 /* RxCollectionViewDataSourceProxy.swift */,
C84969C61B47DE1D00E0BDB9 /* RxCollectionViewDelegateProxy.swift */,
C84969C71B47DE1D00E0BDB9 /* RxScrollViewDelegateProxy.swift */,
C84969C81B47DE1D00E0BDB9 /* RxTableViewDataSourceProxy.swift */,
C84969C91B47DE1D00E0BDB9 /* RxTableViewDelegateProxy.swift */,
);
path = Proxies;
sourceTree = "<group>";
};
C86282301B36037100500DC3 /* Observables */ = {
isa = PBXGroup;
children = (
@ -258,10 +233,9 @@
children = (
C86282301B36037100500DC3 /* Observables */,
C80B562A1B2E242D008F915D /* Delegate.swift */,
C8D95C161B2F0CD700FA661F /* DelegateBridgeType.swift */,
C8D95C161B2F0CD700FA661F /* DelegateProxyType.swift */,
C8633AAC1B093EDF00375D60 /* Logging.swift */,
C8633AAF1B093EDF00375D60 /* RxCocoa.swift */,
C88C788B1B3EBA050061C5AB /* DelegateConverterType.swift */,
);
path = Common;
sourceTree = "<group>";
@ -269,10 +243,9 @@
C88BB8DE1B07F2100064D411 /* iOS */ = {
isa = PBXGroup;
children = (
C84969C41B47DE1D00E0BDB9 /* Proxies */,
C8AED7DE1B3CC12A00678DDE /* DataSources */,
C8AED7D71B3CAA3A00678DDE /* Protocols */,
C8AED7BA1B3C91B700678DDE /* Bridges */,
C8AED7C11B3C91B700678DDE /* Delegates */,
C862824D1B370C7E00500DC3 /* Events */,
C86282491B3607D500500DC3 /* CoreDataEntityEvent.swift */,
C80B56211B2DFCA0008F915D /* NSManagedObjectContext+Rx.swift */,
@ -304,41 +277,11 @@
path = OSX;
sourceTree = "<group>";
};
C8AED7BA1B3C91B700678DDE /* Bridges */ = {
isa = PBXGroup;
children = (
C8AED7BC1B3C91B700678DDE /* RxScrollViewDelegateBridge.swift */,
C8AED7BE1B3C91B700678DDE /* RxTableViewDataSourceBridge.swift */,
C8AED7C01B3C91B700678DDE /* RxTableViewDelegateBridge.swift */,
C8A57F7B1B41438700D5570A /* RxCollectionViewDataSourceBridge.swift */,
C8A57F7F1B41478A00D5570A /* RxCollectionViewDelegateBridge.swift */,
);
path = Bridges;
sourceTree = "<group>";
};
C8AED7C11B3C91B700678DDE /* Delegates */ = {
isa = PBXGroup;
children = (
C83CF87A1B3DFDF8001359E7 /* RxScrollViewDelegateConverter.swift */,
C83CF87C1B3E0316001359E7 /* RxScrollViewNopDelegate.swift */,
C83CF87E1B3E0A25001359E7 /* RxTableViewDelegateConverter.swift */,
C83CF8801B3E0B9D001359E7 /* RxTableViewNopDelegate.swift */,
C8A57F7D1B41464C00D5570A /* RxCollectionViewNopDelegate.swift */,
C8A57F811B41479A00D5570A /* RxCollectionViewDelegateConverter.swift */,
);
path = Delegates;
sourceTree = "<group>";
};
C8AED7D71B3CAA3A00678DDE /* Protocols */ = {
isa = PBXGroup;
children = (
C8AED7D81B3CAA4F00678DDE /* RxTableViewDataSourceType.swift */,
C8AED7E81B3CC93600678DDE /* RxTableViewReactiveDataSourceType.swift */,
C83CF8761B3DE811001359E7 /* RxScrollViewDelegateType.swift */,
C83CF8781B3DE923001359E7 /* RxTableViewDelegateType.swift */,
C8A57F751B4141CC00D5570A /* RxCollectionViewDataSourceType.swift */,
C8A57F771B41424800D5570A /* RxCollectionViewDelegateType.swift */,
C8A57F791B41431600D5570A /* RxCollectionViewReactiveDataSourceType.swift */,
C8AED7E81B3CC93600678DDE /* RxTableViewDataSourceType.swift */,
C8A57F791B41431600D5570A /* RxCollectionViewDataSourceType.swift */,
);
path = Protocols;
sourceTree = "<group>";
@ -346,11 +289,7 @@
C8AED7DE1B3CC12A00678DDE /* DataSources */ = {
isa = PBXGroup;
children = (
C8AED7E51B3CC60300678DDE /* RxTableViewNopDataSource.swift */,
C8AED7EB1B3D4F3700678DDE /* RxTableViewDataSourceConverter.swift */,
C83CF8621B3DDD54001359E7 /* RxTableViewReactiveArrayDataSource.swift */,
C8A57F831B41514E00D5570A /* RxCollectionViewNopDataSource.swift */,
C8A57F851B41520C00D5570A /* RxCollectionViewDataSourceConverter.swift */,
C8A57F871B41530A00D5570A /* RxCollectionViewReactiveArrayDataSource.swift */,
);
path = DataSources;
@ -470,56 +409,40 @@
buildActionMask = 2147483647;
files = (
C86282391B36037100500DC3 /* ControlTarget.swift in Sources */,
C8A57F761B4141CC00D5570A /* RxCollectionViewDataSourceType.swift in Sources */,
C88BB8EE1B07F2BE0064D411 /* UITableView+Rx.swift in Sources */,
C8A57F7C1B41438700D5570A /* RxCollectionViewDataSourceBridge.swift in Sources */,
C88BB8EF1B07F2BE0064D411 /* UITextField+Rx.swift in Sources */,
C8A57F7A1B41431600D5570A /* RxCollectionViewReactiveDataSourceType.swift in Sources */,
C8A57F821B41479A00D5570A /* RxCollectionViewDelegateConverter.swift in Sources */,
C8A57F7A1B41431600D5570A /* RxCollectionViewDataSourceType.swift in Sources */,
C862823B1B36037100500DC3 /* KVOObservable.swift in Sources */,
C83CF8811B3E0B9D001359E7 /* RxTableViewNopDelegate.swift in Sources */,
C83CF8771B3DE811001359E7 /* RxScrollViewDelegateType.swift in Sources */,
493693671B173C8F006FA450 /* UISlider+Rx.swift in Sources */,
C8A57F841B41514E00D5570A /* RxCollectionViewNopDataSource.swift in Sources */,
C8A57F861B41520C00D5570A /* RxCollectionViewDataSourceConverter.swift in Sources */,
C862823D1B36037100500DC3 /* NSNotificationCenter+Rx.swift in Sources */,
C84969CE1B47DE1D00E0BDB9 /* RxTableViewDelegateProxy.swift in Sources */,
C86282501B370C7E00500DC3 /* ItemEvents.swift in Sources */,
C83225471B1A9CCB0048EC77 /* UIDatePicker.swift in Sources */,
C83225451B1A9ACC0048EC77 /* UIBarButtonItem.swift in Sources */,
C8AED7CC1B3C91B700678DDE /* RxTableViewDelegateBridge.swift in Sources */,
C83CF8631B3DDD54001359E7 /* RxTableViewReactiveArrayDataSource.swift in Sources */,
C83CF87B1B3DFDF8001359E7 /* RxScrollViewDelegateConverter.swift in Sources */,
C8A57F7E1B41464C00D5570A /* RxCollectionViewNopDelegate.swift in Sources */,
C86282441B36038800500DC3 /* Derive.swift in Sources */,
C8A57F801B41478A00D5570A /* RxCollectionViewDelegateBridge.swift in Sources */,
C84969CB1B47DE1D00E0BDB9 /* RxCollectionViewDelegateProxy.swift in Sources */,
C84969CC1B47DE1D00E0BDB9 /* RxScrollViewDelegateProxy.swift in Sources */,
C88BB8E81B07F2BE0064D411 /* UIButton+Rx.swift in Sources */,
C86282471B36038F00500DC3 /* Integrate.swift in Sources */,
C8633AB41B093EDF00375D60 /* Logging.swift in Sources */,
C862823F1B36037100500DC3 /* NSURLSession+Rx.swift in Sources */,
C8AED7D91B3CAA4F00678DDE /* RxTableViewDataSourceType.swift in Sources */,
C88C788C1B3EBA050061C5AB /* DelegateConverterType.swift in Sources */,
C83CF87F1B3E0A25001359E7 /* RxTableViewDelegateConverter.swift in Sources */,
C8AED7EC1B3D4F3700678DDE /* RxTableViewDataSourceConverter.swift in Sources */,
C88BB8EB1B07F2BE0064D411 /* UILabel+Rx.swift in Sources */,
C80B56221B2DFCA0008F915D /* NSManagedObjectContext+Rx.swift in Sources */,
C88BB8E91B07F2BE0064D411 /* UICollectionView+Rx.swift in Sources */,
C862824A1B3607D500500DC3 /* CoreDataEntityEvent.swift in Sources */,
C8A57F781B41424800D5570A /* RxCollectionViewDelegateType.swift in Sources */,
C84969CD1B47DE1D00E0BDB9 /* RxTableViewDataSourceProxy.swift in Sources */,
C8633ABA1B093EDF00375D60 /* RxCocoa.swift in Sources */,
C8AED7E61B3CC60300678DDE /* RxTableViewNopDataSource.swift in Sources */,
C88BB8ED1B07F2BE0064D411 /* UISearchBar+Rx.swift in Sources */,
C83CF8791B3DE923001359E7 /* RxTableViewDelegateType.swift in Sources */,
C8AED7C41B3C91B700678DDE /* RxScrollViewDelegateBridge.swift in Sources */,
C88BB8EA1B07F2BE0064D411 /* UIImageView+Rx.swift in Sources */,
C83CF87D1B3E0316001359E7 /* RxScrollViewNopDelegate.swift in Sources */,
C88BB8EC1B07F2BE0064D411 /* UIScrollView+Rx.swift in Sources */,
C86282411B36037100500DC3 /* Observable+IncrementalUpdates.swift in Sources */,
C84969CA1B47DE1D00E0BDB9 /* RxCollectionViewDataSourceProxy.swift in Sources */,
C80B562B1B2E242D008F915D /* Delegate.swift in Sources */,
C8AED7C81B3C91B700678DDE /* RxTableViewDataSourceBridge.swift in Sources */,
653C8BF41B114EB600983087 /* UIControl+Rx.swift in Sources */,
C8A57F881B41530A00D5570A /* RxCollectionViewReactiveArrayDataSource.swift in Sources */,
C8AED7E91B3CC93600678DDE /* RxTableViewReactiveDataSourceType.swift in Sources */,
C8D95C171B2F0CD700FA661F /* DelegateBridgeType.swift in Sources */,
C8AED7E91B3CC93600678DDE /* RxTableViewDataSourceType.swift in Sources */,
C8D95C171B2F0CD700FA661F /* DelegateProxyType.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -530,23 +453,18 @@
C80B562C1B2E242D008F915D /* Delegate.swift in Sources */,
C86282401B36037100500DC3 /* NSURLSession+Rx.swift in Sources */,
C862823E1B36037100500DC3 /* NSNotificationCenter+Rx.swift in Sources */,
C8AED7DA1B3CAA4F00678DDE /* RxTableViewDataSourceType.swift in Sources */,
C88BB91D1B07FD960064D411 /* NSButton+Rx.swift in Sources */,
C8AED7CD1B3C91B700678DDE /* RxTableViewDelegateBridge.swift in Sources */,
C8AED7C91B3C91B700678DDE /* RxTableViewDataSourceBridge.swift in Sources */,
C8AED7C51B3C91B700678DDE /* RxScrollViewDelegateBridge.swift in Sources */,
C86282421B36037100500DC3 /* Observable+IncrementalUpdates.swift in Sources */,
C862823A1B36037100500DC3 /* ControlTarget.swift in Sources */,
C862823C1B36037100500DC3 /* KVOObservable.swift in Sources */,
C8633AB51B093EDF00375D60 /* Logging.swift in Sources */,
C8AED7EA1B3CC93600678DDE /* RxTableViewReactiveDataSourceType.swift in Sources */,
C8AED7EA1B3CC93600678DDE /* RxTableViewDataSourceType.swift in Sources */,
C8633ABB1B093EDF00375D60 /* RxCocoa.swift in Sources */,
C86282451B36038800500DC3 /* Derive.swift in Sources */,
C8633A981B08FD0600375D60 /* NSTextField+Rx.swift in Sources */,
C8D95C181B2F0CD700FA661F /* DelegateBridgeType.swift in Sources */,
C8D95C181B2F0CD700FA661F /* DelegateProxyType.swift in Sources */,
C86282481B36038F00500DC3 /* Integrate.swift in Sources */,
C862824B1B3607D500500DC3 /* CoreDataEntityEvent.swift in Sources */,
C88C788D1B3EBA050061C5AB /* DelegateConverterType.swift in Sources */,
C8633A9A1B08FEBB00375D60 /* NSImageView+Rx.swift in Sources */,
CBEEA67A1B12364200176529 /* NSSlider+Rx.swift in Sources */,
C83225491B1A9ECC0048EC77 /* NSControl+Rx.swift in Sources */,

View File

@ -11,7 +11,7 @@ import RxSwift
// This should be only used from `MainScheduler`
//
// Also, please take a look at `RxDelegateBridge` protocol implementation
// Also, please take a look at `RxDelegateProxy` protocol implementation
public class Delegate : NSObject, Disposable {
private var retainSelf: Delegate! = nil

View File

@ -1,230 +0,0 @@
//
// DelegateBridgeType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/15/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import RxSwift
import UIKit
// `DelegateBridgeType` protocol enables using both normal delegates and Rx observables with
// views that can have only one delegate/datasource registered.
//
// `Bridges` store information about observers, subscriptions and delegates
// for specific views.
//
//
// This is more or less how it works.
//
/*
+-------------------------------------------+
| |
| UIView subclass (UIScrollView) |
| |
+-----------+-------------------------------+
|
| Delegate
|
|
+-----------v-------------------------------+
| |
| Delegate bridge : DelegateBridgeType +-----+----> Observable<T1>
| , UIScrollViewDelegate | |
+-----------+-------------------------------+ +----> Observable<T2>
| |
| rx_bind(delegate) -> Disposable +----> Observable<T3>
| |
| proxies events |
| |
| v
+-----------v-------------------------------+
| |
| Custom delegate (UIScrollViewDelegate) |
| or RxScrollViewDelegate |
+-------------------------------------------+
*/
// Since RxCocoa needs to automagically create those bridges
// ..and because views that have delegates can be hierarchical
//
// UITableView : UIScrollView : UIView
//
// .. and corresponding delegates are also hierarchical
//
// UITableViewDelegate : UIScrollViewDelegate : NSObject
//
// .. and sometimes there can be only one bridge/delegate registered,
// every view has a corresponding delegate virtual factory method.
//
// In case of UITableView / UIScrollView, there is
//
// ```
// extensions UIScrollView {
// public func rx_createDelegateBridge() -> RxScrollViewDelegateBridge {
// return RxScrollViewDelegateBridge(view: self)
// }
//
// ....
// ```
//
// and override in UITableView
//
//```
// extension UITableView {
// public override func rx_createDelegateBridge() -> RxScrollViewDelegateBridge {
// ....
//```
//
// =============================================================================
//
// But there is more :)
//
// Unfortunately, Swift generic classes can't inherit from `UI[UKitView]Delegate` protocols.
// That means that one would need to create its own swift proxy class to implement generic
// data source or delegates.
//
// But since RxCocoa already has Swift classes that are bridges for ObjC protocols, why not use
// them and enable generic Swift data sources and delegates.
//
// That's exactly what `Rx[UIKitView]DelegateType` set of protocols are for.
//
// Since swift bridge classes already exist, RxCocoa project defines it's own set of delegates.
// They implement exactly same methods like their original UIKit mirror delegates.
// In that case, if you already have some delegate logic that implements `[UIKitView]Delegate`
// it should be pretty straightforward to incorporate it with RxCocoa project.
//
// =============================================================================
//
// But there is more :)
//
// It would be kind of impolite to require users to fiddle with their existing working
// code, and now suddenly have to use `Rx[UIKitView]DelegateType` set of protocols.
//
// That's why for each Rx protocol there is already a corresponding converter class
// that converts from `[UIView]Delegate` to `Rx[UIView]DelegateType`.
//
// E.g. RxScrollViewDelegateConverter is adapter for UIScrollViewDelegate
//
// =============================================================================
//
// But there is more :)
//
// In case you want to use `Rx[UIView]DelegateType` protocols, Swift unfortunately doesn't
// support optional methods in protocols.
//
// That's why for each `Rx[UIView]DelegateType` protocol there is already
// `Rx[UIKitView]NopDelegate` implementation provided.
//
// It enables you to define just those methods that you really care about in your delegate
// implementation.
// Methods that aren't overriden will use default implementation from NopDelegate that
// don't do anything.
//
public protocol DelegateBridgeType : Disposable {
// tried, it didn't work out
// typealias View
static func createBridgeForView(view: UIView) -> Self
// tried using `Self` instead of Any object, didn't work out
static func getBridgeForView(view: UIView) -> Self?
static func setBridgeToView(view: UIView, bridge: AnyObject)
func setDelegate(delegate: AnyObject?)
func getDelegate() -> AnyObject?
var isDisposable: Bool { get }
}
struct BridgeDisposablePair<B> {
let bridge: B
let disposable: Disposable
}
func performOnInstalledBridge<B: DelegateBridgeType, R>(view: UIView, actionOnBridge: (B) -> R) -> R {
MainScheduler.ensureExecutingOnScheduler()
let maybeBridge: B? = B.getBridgeForView(view)
let bridge: B
if maybeBridge != nil {
bridge = maybeBridge!
}
else {
bridge = B.createBridgeForView(view)
B.setBridgeToView(view, bridge: bridge)
assert(B.getBridgeForView(view) === bridge, "Bridge is not the same")
}
assert(B.getBridgeForView(view) !== nil, "There should be bridge registered.")
return actionOnBridge(bridge)
}
func installDelegateOnBridge<B: DelegateBridgeType>(view: UIView, delegate: AnyObject) -> BridgeDisposablePair<B> {
return performOnInstalledBridge(view) { (bridge: B) in
assert(bridge.getDelegate() === nil, "There is already a set delegate \(bridge.getDelegate())")
bridge.setDelegate(delegate)
assert(bridge.getDelegate() === delegate, "Setting of delegate failed")
let result = BridgeDisposablePair(bridge: bridge, disposable: AnonymousDisposable {
MainScheduler.ensureExecutingOnScheduler()
assert(bridge.getDelegate() === delegate, "Delegate was changed from time it was first set. Current \(bridge.getDelegate()), and it should have been \(bridge)")
bridge.setDelegate(nil)
if bridge.isDisposable {
bridge.dispose()
}
})
return result
}
}
func createObservableUsingDelegateBridge<B: DelegateBridgeType, Element, DisposeKey>(view: UIView,
addObserver: (B, ObserverOf<Element>) -> DisposeKey,
removeObserver: (B, DisposeKey) -> ())
-> Observable<Element> {
return AnonymousObservable { observer in
return performOnInstalledBridge(view) { (bridge: B) in
let key = addObserver(bridge, observer)
return AnonymousDisposable {
MainScheduler.ensureExecutingOnScheduler()
removeObserver(bridge, key)
if bridge.isDisposable {
bridge.dispose()
}
}
}
}
}
func subscribeObservableUsingDelegateBridgeAndDataSource<B: DelegateBridgeType, Element>(view: UIView, dataSource: AnyObject, binding: (B, Event<Element>) -> Void)
-> Observable<Element> -> Disposable {
return { source in
let result: BridgeDisposablePair<B> = installDelegateOnBridge(view, dataSource)
let bridge = result.bridge
let subscription = source.subscribe(AnonymousObserver { event in
MainScheduler.ensureExecutingOnScheduler()
assert(bridge === B.getBridgeForView(view), "Bridge changed from the time it was first set.\nOriginal: \(bridge)\nExisting: \(B.getBridgeForView(view))")
binding(bridge, event)
})
return StableCompositeDisposable.create(subscription, result.disposable)
}
}

View File

@ -1,24 +0,0 @@
//
// DelegateConverterType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/27/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
// If all delegate methods are implemented by just returning dummy values
// some of the behavior is lost.
//
// E.g. UITableView won't who section headers.
//
// To remedy that, this enables `Rx[UIView]DelegateType`
// to return proxy that answers can it respond to selector.
//
// This kind of brings back optional methods for `Rx[UIView]DelegateType`
public protocol DelegateConverterType {
var targetDelegate: NSObjectProtocol? {
get
}
}

View File

@ -0,0 +1,185 @@
//
// DelegateProxyType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/15/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import RxSwift
import UIKit
// `DelegateProxyType` protocol enables using both normal delegates and Rx observables with
// views that can have only one delegate/datasource registered.
//
// `Proxys` store information about observers, subscriptions and delegates
// for specific views.
//
//
// This is more or less how it works.
//
/*
+-------------------------------------------+
| |
| UIView subclass (UIScrollView) |
| |
+-----------+-------------------------------+
|
| Delegate
|
|
+-----------v-------------------------------+
| |
| Delegate proxy : DelegateProxyType +-----+----> Observable<T1>
| , UIScrollViewDelegate | |
+-----------+-------------------------------+ +----> Observable<T2>
| |
| rx_bind(delegate) -> Disposable +----> Observable<T3>
| |
| proxies events |
| |
| v
+-----------v-------------------------------+
| |
| Custom delegate (UIScrollViewDelegate) |
| |
+-------------------------------------------+
*/
// Since RxCocoa needs to automagically create those Proxys
// ..and because views that have delegates can be hierarchical
//
// UITableView : UIScrollView : UIView
//
// .. and corresponding delegates are also hierarchical
//
// UITableViewDelegate : UIScrollViewDelegate : NSObject
//
// .. and sometimes there can be only one proxy/delegate registered,
// every view has a corresponding delegate virtual factory method.
//
// In case of UITableView / UIScrollView, there is
//
// ```
// extensions UIScrollView {
// public func rx_createDelegateProxy() -> RxScrollViewDelegateProxy {
// return RxScrollViewDelegateProxy(view: self)
// }
//
// ....
// ```
//
// and override in UITableView
//
//```
// extension UITableView {
// public override func rx_createDelegateProxy() -> RxScrollViewDelegateProxy {
// ....
//```
//
public protocol DelegateProxyType : Disposable {
// tried, it didn't work out
// typealias View
static func createProxyForView(view: UIView) -> Self
// tried using `Self` instead of Any object, didn't work out
static func getProxyForView(view: UIView) -> Self?
static func setProxyToView(view: UIView, proxy: AnyObject)
func setDelegate(delegate: AnyObject?)
func getDelegate() -> AnyObject?
var isDisposable: Bool { get }
}
struct ProxyDisposablePair<B> {
let proxy: B
let disposable: Disposable
}
func performOnInstalledProxy<B: DelegateProxyType, R>(view: UIView, actionOnProxy: (B) -> R) -> R {
MainScheduler.ensureExecutingOnScheduler()
let maybeProxy: B? = B.getProxyForView(view)
let proxy: B
if maybeProxy != nil {
proxy = maybeProxy!
}
else {
proxy = B.createProxyForView(view)
B.setProxyToView(view, proxy: proxy)
assert(B.getProxyForView(view) === proxy, "Proxy is not the same")
}
assert(B.getProxyForView(view) !== nil, "There should be proxy registered.")
return actionOnProxy(proxy)
}
func installDelegateOnProxy<B: DelegateProxyType>(view: UIView, delegate: AnyObject) -> ProxyDisposablePair<B> {
return performOnInstalledProxy(view) { (proxy: B) in
assert(proxy.getDelegate() === nil, "There is already a set delegate \(proxy.getDelegate())")
proxy.setDelegate(delegate)
assert(proxy.getDelegate() === delegate, "Setting of delegate failed")
let result = ProxyDisposablePair(proxy: proxy, disposable: AnonymousDisposable {
MainScheduler.ensureExecutingOnScheduler()
assert(proxy.getDelegate() === delegate, "Delegate was changed from time it was first set. Current \(proxy.getDelegate()), and it should have been \(proxy)")
proxy.setDelegate(nil)
if proxy.isDisposable {
proxy.dispose()
}
})
return result
}
}
func createObservableUsingDelegateProxy<B: DelegateProxyType, Element, DisposeKey>(view: UIView,
addObserver: (B, ObserverOf<Element>) -> DisposeKey,
removeObserver: (B, DisposeKey) -> ())
-> Observable<Element> {
return AnonymousObservable { observer in
return performOnInstalledProxy(view) { (proxy: B) in
let key = addObserver(proxy, observer)
return AnonymousDisposable {
MainScheduler.ensureExecutingOnScheduler()
removeObserver(proxy, key)
if proxy.isDisposable {
proxy.dispose()
}
}
}
}
}
func subscribeObservableUsingDelegateProxyAndDataSource<B: DelegateProxyType, Element>(view: UIView, dataSource: AnyObject, binding: (B, Event<Element>) -> Void)
-> Observable<Element> -> Disposable {
return { source in
let result: ProxyDisposablePair<B> = installDelegateOnProxy(view, dataSource)
let proxy = result.proxy
let subscription = source.subscribe(AnonymousObserver { event in
MainScheduler.ensureExecutingOnScheduler()
assert(proxy === B.getProxyForView(view), "Proxy changed from the time it was first set.\nOriginal: \(proxy)\nExisting: \(B.getProxyForView(view))")
binding(proxy, event)
})
return StableCompositeDisposable.create(subscription, result.disposable)
}
}

View File

@ -1,135 +0,0 @@
//
// RxCollectionViewDelegateBridge.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxCollectionViewDelegateBridge : RxScrollViewDelegateBridge
, UICollectionViewDelegate {
public typealias ItemSelectedObserver = ObserverOf<ItemSelectedEvent<UICollectionView>>
public typealias ItemSelectedDisposeKey = Bag<ItemSelectedObserver>.KeyType
public let collectionView: UICollectionView
var itemSelectedObservers: Bag<ItemSelectedObserver> = Bag()
var collectionViewDelegate: RxCollectionViewDelegateType?
public override init(view: UIView) {
self.collectionView = view as! UICollectionView
super.init(view: view)
}
public func addItemSelectedObserver(observer: ItemSelectedObserver) -> ItemSelectedDisposeKey {
return itemSelectedObservers.put(observer)
}
public func removeItemSelectedObserver(key: ItemSelectedDisposeKey) {
let element = itemSelectedObservers.removeKey(key)
if element == nil {
removingObserverFailed()
}
}
// delegate methods
public func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return collectionViewDelegate?.collectionView(collectionView, shouldHighlightItemAtIndexPath: indexPath) ?? true
}
public func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate?.collectionView(collectionView, didHighlightItemAtIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate?.collectionView(collectionView, didUnhighlightItemAtIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return collectionViewDelegate?.collectionView(collectionView, shouldSelectItemAtIndexPath: indexPath) ?? true
}
public func collectionView(collectionView: UICollectionView, shouldDeselectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return collectionViewDelegate?.collectionView(collectionView, shouldDeselectItemAtIndexPath: indexPath) ?? true
}
public func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate?.collectionView(collectionView, didSelectItemAtIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate?.collectionView(collectionView, didDeselectItemAtIndexPath: indexPath)
}
@availability(iOS, introduced=8.0)
public func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate?.collectionView(collectionView, willDisplayCell: cell, forItemAtIndexPath: indexPath)
}
@availability(iOS, introduced=8.0)
public func collectionView(collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, atIndexPath indexPath: NSIndexPath) {
collectionViewDelegate?.collectionView(collectionView, willDisplaySupplementaryView: view, forElementKind: elementKind, atIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate?.collectionView(collectionView, didEndDisplayingCell: cell, forItemAtIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, didEndDisplayingSupplementaryView view: UICollectionReusableView, forElementOfKind elementKind: String, atIndexPath indexPath: NSIndexPath) {
collectionViewDelegate?.collectionView(collectionView, didEndDisplayingSupplementaryView: view, forElementOfKind: elementKind, atIndexPath: indexPath)
}
// These methods provide support for copy/paste actions on cells.
// All three should be implemented if any are.
public func collectionView(collectionView: UICollectionView, shouldShowMenuForItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return collectionViewDelegate?.collectionView(collectionView, shouldShowMenuForItemAtIndexPath: indexPath) ?? false
}
public func collectionView(collectionView: UICollectionView, canPerformAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) -> Bool {
return collectionViewDelegate?.collectionView(collectionView, canPerformAction: action, forItemAtIndexPath: indexPath, withSender: sender) ?? false
}
public func collectionView(collectionView: UICollectionView, performAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) {
collectionViewDelegate?.collectionView(collectionView, performAction: action, forItemAtIndexPath: indexPath, withSender: sender)
}
// support for custom transition layout
public func collectionView(collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout! {
return collectionViewDelegate?.collectionView(collectionView, transitionLayoutForOldLayout: fromLayout, newLayout: toLayout)
}
// delegate bridge
override public class func setBridgeToView(view: UIView, bridge: AnyObject) {
let _: UICollectionViewDelegate = castOrFatalError(bridge)
super.setBridgeToView(view, bridge: bridge)
}
override public func setDelegate(delegate: AnyObject?) {
let typedDelegate: RxCollectionViewDelegateType? = castOptionalOrFatalError(delegate)
self.collectionViewDelegate = typedDelegate
super.setDelegate(delegate)
}
// dispose
public override var isDisposable: Bool {
get {
return super.isDisposable && self.itemSelectedObservers.count == 0
}
}
deinit {
if !isDisposable {
handleVoidObserverResult(failure(rxError(RxCocoaError.InvalidOperation, "Something went wrong. Deallocating collection view delegate while there are still subscribed observers means that some subscription was left undisposed.")))
}
}
}

View File

@ -1,279 +0,0 @@
//
// RxTableViewDelegateBridge.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/15/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Need to exclude this if not defined, otherwise UITableView will transfer control
// to delegate in cases when it shouldn't.
let possiblyExcludeForwardSelectorsToTableViewDelegateBridge: [Selector: Bool] = [
"tableView:heightForRowAtIndexPath:" : true,
"tableView:heightForHeaderInSection:" : true,
"tableView:heightForFooterInSection:" : true,
"tableView:viewForHeaderInSection:" : true,
"tableView:viewForFooterInSection:" : true,
"viewForHeaderInTableView:" : true,
"viewForFooterInTableView" : true,
"tableView:estimatedHeightForRowAtIndexPath:" : true,
"tableView:estimatedHeightForHeaderInSection:" : true,
"tableView:estimatedHeightForFooterInSection:" : true,
]
// Please take a look at `DelegateBridgeType.swift`
public class RxTableViewDelegateBridgeWithProxyFiltering: RxTableViewDelegateBridge {
public override init(view: UIView) {
super.init(view: view)
}
var targetDelegate: NSObjectProtocol?
public override func setDelegate(delegate: AnyObject?) {
targetDelegate = (delegate as? DelegateConverterType)?.targetDelegate
super.setDelegate(delegate)
}
// proxy
public override func respondsToSelector(aSelector: Selector) -> Bool {
if possiblyExcludeForwardSelectorsToTableViewDelegateBridge[aSelector] != nil {
return self.targetDelegate?.respondsToSelector(aSelector) ?? false
}
return RxTableViewDelegateBridgeWithProxyFiltering.instancesRespondToSelector(aSelector)
|| super.respondsToSelector(aSelector)
}
}
// Please take a look at `DelegateBridgeType.swift`
public class RxTableViewDelegateBridge : RxScrollViewDelegateBridge
, UITableViewDelegate {
public typealias ItemSelectedObserver = ObserverOf<ItemSelectedEvent<UITableView>>
public typealias ItemSelectedDisposeKey = Bag<ItemSelectedObserver>.KeyType
public let tableView: UITableView
var itemSelectedObservers: Bag<ItemSelectedObserver> = Bag()
var tableViewDelegate: RxTableViewDelegateType?
public override init(view: UIView) {
self.tableView = view as! UITableView
super.init(view: view)
}
public func addItemSelectedObserver(observer: ItemSelectedObserver) -> ItemSelectedDisposeKey {
return itemSelectedObservers.put(observer)
}
public func removeItemSelectedObserver(key: ItemSelectedDisposeKey) {
let element = itemSelectedObservers.removeKey(key)
if element == nil {
removingObserverFailed()
}
}
// Display customization
public func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate?.tableView(tableView, willDisplayCell: cell, forRowAtIndexPath: indexPath)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
tableViewDelegate?.tableView(tableView, willDisplayHeaderView: view, forSection: section)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) {
tableViewDelegate?.tableView(tableView, willDisplayFooterView: view, forSection: section)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate?.tableView(tableView, didEndDisplayingCell: cell, forRowAtIndexPath: indexPath)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {
tableViewDelegate?.tableView(tableView, didEndDisplayingHeaderView: view, forSection: section)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingFooterView view: UIView, forSection section: Int) {
tableViewDelegate?.tableView(tableView, didEndDisplayingFooterView: view, forSection: section)
}
// Variable height support
public func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableViewDelegate?.tableView(tableView, heightForRowAtIndexPath: indexPath) ?? defaultHeight
}
public func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return tableViewDelegate?.tableView(tableView, heightForHeaderInSection: section) ?? defaultHeight
}
public func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return tableViewDelegate?.tableView(tableView, heightForFooterInSection: section) ?? defaultHeight
}
// Use the estimatedHeight methods to quickly calcuate guessed values which will allow for fast load times of the table.
// If these methods are implemented, the above -tableView:heightForXXX calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableViewDelegate?.tableView(tableView, estimatedHeightForRowAtIndexPath: indexPath) ?? defaultHeight
}
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return tableViewDelegate?.tableView(tableView, estimatedHeightForHeaderInSection: section) ?? 0
}
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat {
return tableViewDelegate?.tableView(tableView, estimatedHeightForFooterInSection: section) ?? 0
}
// Section header & footer information. Views are preferred over title should you decide to provide both
public func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? // custom view for header. will be adjusted to default or specified header height
{
return tableViewDelegate?.tableView(tableView, viewForHeaderInSection: section) ?? nil
}
public func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? // custom view for footer. will be adjusted to default or specified footer height
{
return tableViewDelegate?.tableView(tableView, viewForFooterInSection: section) ?? nil
}
// Accessories (disclosures).
public func tableView(tableView: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath)
{
tableViewDelegate?.tableView(tableView, accessoryButtonTappedForRowWithIndexPath: indexPath)
}
// Selection
// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
// Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return tableViewDelegate?.tableView(tableView, shouldHighlightRowAtIndexPath: indexPath) ?? true
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate?.tableView(tableView, didHighlightRowAtIndexPath: indexPath)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate?.tableView(tableView, didUnhighlightRowAtIndexPath: indexPath)
}
// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
public func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
return tableViewDelegate?.tableView(tableView, willSelectRowAtIndexPath: indexPath) ?? nil
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, willDeselectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
return tableViewDelegate?.tableView(tableView, willDeselectRowAtIndexPath: indexPath) ?? nil
}
// Called after the user changes the selection.
public func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
dispatchNext(ItemSelectedEvent<UITableView>(view: tableView, indexPath: indexPath), itemSelectedObservers)
tableViewDelegate?.tableView(tableView, didSelectRowAtIndexPath: indexPath)
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate?.tableView(tableView, didDeselectRowAtIndexPath: indexPath)
}
// Editing
// Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
public func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return tableViewDelegate?.tableView(tableView, editingStyleForRowAtIndexPath: indexPath) ?? .None
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String! {
return tableViewDelegate?.tableView(tableView, titleForDeleteConfirmationButtonForRowAtIndexPath: indexPath) ?? nil
}
@availability(iOS, introduced=8.0)
public func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? // supercedes -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil
{
return tableViewDelegate?.tableView(tableView, editActionsForRowAtIndexPath: indexPath) ?? nil
}
// Controls whether the background is indented while editing. If not implemented, the default is YES. This is unrelated to the indentation level below. This method only applies to grouped style table views.
public func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return tableViewDelegate?.tableView(tableView, shouldIndentWhileEditingRowAtIndexPath: indexPath) ?? true
}
// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
public func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate?.tableView(tableView, willBeginEditingRowAtIndexPath: indexPath)
}
public func tableView(tableView: UITableView, didEndEditingRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate?.tableView(tableView, didEndEditingRowAtIndexPath: indexPath)
}
// Moving/reordering
// Allows customization of the target row for a particular row as it is being moved/reordered
public func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
return tableViewDelegate?.tableView(tableView, targetIndexPathForMoveFromRowAtIndexPath: sourceIndexPath, toProposedIndexPath: proposedDestinationIndexPath) ?? proposedDestinationIndexPath
}
// Indentation
public func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int // return 'depth' of row for hierarchies
{
return tableViewDelegate?.tableView(tableView, indentationLevelForRowAtIndexPath: indexPath) ?? 0
}
// Copy/Paste. All three methods must be implemented by the delegate.
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, shouldShowMenuForRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return tableViewDelegate?.tableView(tableView, shouldShowMenuForRowAtIndexPath: indexPath) ?? false
}
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, canPerformAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject) -> Bool {
return tableViewDelegate?.tableView(tableView, canPerformAction: action, forRowAtIndexPath: indexPath, withSender: sender) ?? false
}
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, performAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) {
tableViewDelegate?.tableView(tableView, performAction: action, forRowAtIndexPath: indexPath, withSender: sender)
}
// delegate bridge
override public class func setBridgeToView(view: UIView, bridge: AnyObject) {
let _: UITableViewDelegate = castOrFatalError(bridge)
super.setBridgeToView(view, bridge: bridge)
}
override public func setDelegate(delegate: AnyObject?) {
let typedDelegate: RxTableViewDelegateType? = castOptionalOrFatalError(delegate)
self.tableViewDelegate = typedDelegate
super.setDelegate(delegate)
}
public override var isDisposable: Bool {
get {
return super.isDisposable && self.itemSelectedObservers.count == 0
}
}
// dispose
deinit {
if !isDisposable {
handleVoidObserverResult(failure(rxError(RxCocoaError.InvalidOperation, "Something went wrong. Deallocating table view delegate while there are still subscribed observers means that some subscription was left undisposed.")))
}
}
}

View File

@ -1,61 +0,0 @@
//
// RxCollectionViewDataSourceConverter.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxCollectionViewDataSourceConverter : RxCollectionViewDataSourceType
, DelegateConverterType {
unowned let dataSource: UICollectionViewDataSource
let strongDataSource: UICollectionViewDataSource?
public init(dataSource: UICollectionViewDataSource, retainDataSource: Bool) {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
self.strongDataSource = retainDataSource ? dataSource : nil
self.dataSource = dataSource
}
// converter
public var targetDelegate: NSObjectProtocol? {
get {
return dataSource
}
}
// copied methods from UICollectionViewDataSource
public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource.collectionView(collectionView, numberOfItemsInSection: section)
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return dataSource.collectionView(collectionView, cellForItemAtIndexPath: indexPath)
}
public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return dataSource.numberOfSectionsInCollectionView?(collectionView) ?? 1
}
// The view that is returned must be retrieved from a call to -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
public func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
return dataSource.collectionView?(collectionView, viewForSupplementaryElementOfKind: kind, atIndexPath: indexPath) ?? rxAbstractMethod()
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -1,41 +0,0 @@
//
// RxCollectionViewNopDataSource.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxCollectionViewNopDataSource {
public init() {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
}
// copied methods from UICollectionViewDataSource
public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 0
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return rxAbstractMethod()
}
public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -10,13 +10,36 @@ import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxCollectionViewReactiveArrayDataSource<ElementType> : RxCollectionViewNopDataSource
, RxCollectionViewReactiveDataSourceType {
// objc monkey business
public class _RxCollectionViewReactiveArrayDataSource: NSObject, UICollectionViewDataSource {
public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func _collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 0
}
public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return _collectionView(collectionView, numberOfItemsInSection: section)
}
func _collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return rxAbstractMethod()
}
public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return _collectionView(collectionView, cellForItemAtIndexPath: indexPath)
}
}
// Please take a look at `DelegateProxyType.swift`
public class RxCollectionViewReactiveArrayDataSource<ElementType> : _RxCollectionViewReactiveArrayDataSource
, RxCollectionViewDataSourceType {
typealias Element = [ElementType]
typealias CellFactory = (UICollectionView, NSIndexPath, ElementType) -> UICollectionViewCell
typealias SupplementaryViewFactory = (UICollectionView, String, NSIndexPath, ElementType) -> UICollectionReusableView
var itemModels: [ElementType]? = nil
@ -25,31 +48,21 @@ public class RxCollectionViewReactiveArrayDataSource<ElementType> : RxCollection
}
public var cellFactory: CellFactory
public var supplementaryViewFactory: SupplementaryViewFactory
init(cellFactory: CellFactory) {
self.cellFactory = cellFactory
self.supplementaryViewFactory = { (_, _, _, _) in
rxFatalError("Supplementary view factory not set")
return rxAbstractMethod()
}
}
// data source
public override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
override func _collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return itemModels?.count ?? 0
}
public override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
override func _collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return cellFactory(collectionView, indexPath, itemModels![indexPath.item])
}
public func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
return supplementaryViewFactory(collectionView, kind, indexPath, itemModels![indexPath.item])
}
// reactive
public func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) {

View File

@ -1,87 +0,0 @@
//
// RxTableViewDataSourceConverter.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/26/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxTableViewDataSourceConverter : RxTableViewDataSourceType
, DelegateConverterType {
unowned let dataSource: UITableViewDataSource
let strongDataSource: UITableViewDataSource?
public init(dataSource: UITableViewDataSource, retainDataSource: Bool) {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
self.strongDataSource = retainDataSource ? dataSource : nil
self.dataSource = dataSource
}
// converter
public var targetDelegate: NSObjectProtocol? {
get {
return dataSource
}
}
// data source
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataSource.tableView(tableView, numberOfRowsInSection: section) ?? 0
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return self.dataSource.tableView(tableView, cellForRowAtIndexPath: indexPath)
}
public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.dataSource.numberOfSectionsInTableView?(tableView) ?? 1
}
public func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.dataSource.tableView?(tableView, titleForHeaderInSection: section)
}
public func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return self.dataSource.tableView?(tableView, titleForFooterInSection: section)
}
public func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return self.dataSource.tableView?(tableView, canEditRowAtIndexPath: indexPath) ?? false
}
public func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return self.dataSource.tableView?(tableView, canMoveRowAtIndexPath: indexPath) ?? false
}
public func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! {
return self.dataSource.sectionIndexTitlesForTableView?(tableView)
}
public func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return self.dataSource.tableView?(tableView, sectionForSectionIndexTitle: title, atIndex: index) ?? 0
}
public func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
self.dataSource.tableView?(tableView, commitEditingStyle: editingStyle, forRowAtIndexPath: indexPath)
}
public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
self.dataSource.tableView?(tableView, moveRowAtIndexPath: sourceIndexPath, toIndexPath: destinationIndexPath)
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -1,72 +0,0 @@
//
// RxTableViewNopReactiveDataSource.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/26/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxTableViewNopDataSource : RxTableViewDataSourceType {
public init() {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
}
// standard methods
public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return rxAbstractMethod()
}
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
// less often used methods
public func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! {
return nil
}
public func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return 0
}
public func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return nil
}
public func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return nil
}
public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
}
public func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
}
public func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
public func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -10,8 +10,34 @@ import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxTableViewReactiveArrayDataSource<ElementType> : RxTableViewNopDataSource, RxTableViewReactiveDataSourceType {
// objc monkey business
public class _RxTableViewReactiveArrayDataSource: NSObject, UITableViewDataSource {
public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func _tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return _tableView(tableView, numberOfRowsInSection: section)
}
func _tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return rxAbstractMethod()
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return _tableView(tableView, cellForRowAtIndexPath: indexPath)
}
}
// Please take a look at `DelegateProxyType.swift`
public class RxTableViewReactiveArrayDataSource<ElementType> : _RxTableViewReactiveArrayDataSource
, RxTableViewDataSourceType {
typealias Element = [ElementType]
typealias CellFactory = (UITableView, NSIndexPath, ElementType) -> UITableViewCell
@ -28,15 +54,11 @@ public class RxTableViewReactiveArrayDataSource<ElementType> : RxTableViewNopDat
self.cellFactory = cellFactory
}
override public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
override func _tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemModels?.count ?? 0
}
override public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
override func _tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return cellFactory(tableView, indexPath, itemModels![indexPath.row])
}

View File

@ -1,99 +0,0 @@
//
// RxCollectionViewDelegateConverter.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxCollectionViewDelegateConverter : RxScrollViewDelegateConverter
, RxCollectionViewDelegateType {
unowned let collectionViewDelegate: UICollectionViewDelegate
let strongCollectionViewDelegate: UICollectionViewDelegate?
public init(delegate: UICollectionViewDelegate, retainDelegate: Bool) {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
self.strongCollectionViewDelegate = retainDelegate ? delegate : nil
self.collectionViewDelegate = delegate
super.init(delegate: delegate, retainDelegate: retainDelegate)
}
public func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return collectionViewDelegate.collectionView?(collectionView, shouldHighlightItemAtIndexPath: indexPath) ?? true
}
public func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate.collectionView?(collectionView, didHighlightItemAtIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate.collectionView?(collectionView, didUnhighlightItemAtIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return collectionViewDelegate.collectionView?(collectionView, shouldSelectItemAtIndexPath: indexPath) ?? true
}
public func collectionView(collectionView: UICollectionView, shouldDeselectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return collectionViewDelegate.collectionView?(collectionView, shouldDeselectItemAtIndexPath: indexPath) ?? true
}
public func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate.collectionView?(collectionView, didSelectItemAtIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate.collectionView?(collectionView, didDeselectItemAtIndexPath: indexPath)
}
@availability(iOS, introduced=8.0)
public func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate.collectionView?(collectionView, willDisplayCell: cell, forItemAtIndexPath: indexPath)
}
@availability(iOS, introduced=8.0)
public func collectionView(collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, atIndexPath indexPath: NSIndexPath) {
collectionViewDelegate.collectionView?(collectionView, willDisplaySupplementaryView: view, forElementKind: elementKind, atIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
collectionViewDelegate.collectionView?(collectionView, didEndDisplayingCell: cell, forItemAtIndexPath: indexPath)
}
public func collectionView(collectionView: UICollectionView, didEndDisplayingSupplementaryView view: UICollectionReusableView, forElementOfKind elementKind: String, atIndexPath indexPath: NSIndexPath) {
collectionViewDelegate.collectionView?(collectionView, didEndDisplayingSupplementaryView: view, forElementOfKind: elementKind, atIndexPath: indexPath)
}
// These methods provide support for copy/paste actions on cells.
// All three should be implemented if any are.
public func collectionView(collectionView: UICollectionView, shouldShowMenuForItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return collectionViewDelegate.collectionView?(collectionView, shouldShowMenuForItemAtIndexPath: indexPath) ?? false
}
public func collectionView(collectionView: UICollectionView, canPerformAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) -> Bool {
return collectionViewDelegate.collectionView?(collectionView, canPerformAction: action, forItemAtIndexPath: indexPath, withSender: sender) ?? false
}
public func collectionView(collectionView: UICollectionView, performAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) {
collectionViewDelegate.collectionView?(collectionView, performAction: action, forItemAtIndexPath: indexPath, withSender: sender)
}
// support for custom transition layout
public func collectionView(collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout! {
return collectionViewDelegate.collectionView?(collectionView, transitionLayoutForOldLayout: fromLayout, newLayout: toLayout)
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -1,93 +0,0 @@
//
// RxCollectionViewNopDelegate.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxCollectionViewNopDelegate : RxScrollViewNopDelegate
, RxCollectionViewDelegateType {
public override init() {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
super.init()
}
public func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
public func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath) {
}
public func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath) {
}
public func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
public func collectionView(collectionView: UICollectionView, shouldDeselectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
public func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
}
public func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
}
@availability(iOS, introduced=8.0)
public func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
}
@availability(iOS, introduced=8.0)
public func collectionView(collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, atIndexPath indexPath: NSIndexPath) {
}
public func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
}
public func collectionView(collectionView: UICollectionView, didEndDisplayingSupplementaryView view: UICollectionReusableView, forElementOfKind elementKind: String, atIndexPath indexPath: NSIndexPath) {
}
// These methods provide support for copy/paste actions on cells.
// All three should be implemented if any are.
public func collectionView(collectionView: UICollectionView, shouldShowMenuForItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
public func collectionView(collectionView: UICollectionView, canPerformAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) -> Bool {
return false
}
public func collectionView(collectionView: UICollectionView, performAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) {
}
// support for custom transition layout
public func collectionView(collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout! {
return nil
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -1,112 +0,0 @@
//
// RxScrollViewDelegateConverter.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/26/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxScrollViewDelegateConverter : RxScrollViewDelegateType
, DelegateConverterType {
unowned let scrollViewDelegate: UIScrollViewDelegate
let strongScrollViewDelegate: UIScrollViewDelegate?
public init(delegate: UIScrollViewDelegate, retainDelegate: Bool) {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
self.strongScrollViewDelegate = retainDelegate ? delegate : nil
self.scrollViewDelegate = delegate
}
// converter
public var targetDelegate: NSObjectProtocol? {
get {
return scrollViewDelegate as? NSObjectProtocol
}
}
// delegate
public func scrollViewDidScroll(scrollView: UIScrollView) // any offset changes
{
scrollViewDelegate.scrollViewDidScroll?(scrollView)
}
@availability(iOS, introduced=3.2)
public func scrollViewDidZoom(scrollView: UIScrollView) // any zoom scale changes
{
scrollViewDelegate.scrollViewDidZoom?(scrollView)
}
// called on start of dragging (may require some time and or distance to move)
public func scrollViewWillBeginDragging(scrollView: UIScrollView)
{
scrollViewDelegate.scrollViewWillBeginDragging?(scrollView)
}
// called on finger up if the user dragged. velocity is in points/millisecond. targetContentOffset may be changed to adjust where the scroll view comes to rest
@availability(iOS, introduced=5.0)
public func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
{
scrollViewDelegate.scrollViewWillEndDragging?(scrollView, withVelocity: velocity, targetContentOffset: targetContentOffset)
}
// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
public func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
{
scrollViewDelegate.scrollViewDidEndDragging?(scrollView, willDecelerate: decelerate)
}
public func scrollViewWillBeginDecelerating(scrollView: UIScrollView) // called on finger up as we are moving
{
scrollViewDelegate.scrollViewWillBeginDecelerating?(scrollView)
}
public func scrollViewDidEndDecelerating(scrollView: UIScrollView) // called when scroll view grinds to a halt
{
scrollViewDelegate.scrollViewDidEndDecelerating?(scrollView)
}
public func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) // called when setContentOffset/scrollRectVisible:animated: finishes. not called if not animating
{
scrollViewDelegate.scrollViewDidEndScrollingAnimation?(scrollView)
}
public func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? // return a view that will be scaled. if delegate returns nil, nothing happens
{
return scrollViewDelegate.viewForZoomingInScrollView?(scrollView) ?? nil
}
@availability(iOS, introduced=3.2)
public func scrollViewWillBeginZooming(scrollView: UIScrollView, withView view: UIView!) // called before the scroll view begins zooming its content
{
scrollViewDelegate.scrollViewWillBeginZooming?(scrollView, withView: view)
}
public func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView!, atScale scale: CGFloat) // scale between minimum and maximum. called after any 'bounce' animations
{
scrollViewDelegate.scrollViewDidEndZooming?(scrollView, withView: view, atScale: scale)
}
public func scrollViewShouldScrollToTop(scrollView: UIScrollView) -> Bool // return a yes if you want to scroll to the top. if not defined, assumes YES
{
return scrollViewDelegate.scrollViewShouldScrollToTop?(scrollView) ?? false
}
public func scrollViewDidScrollToTop(scrollView: UIScrollView) // called when scrolling animation finished. may be called immediately if already at top
{
scrollViewDelegate.scrollViewDidScrollToTop?(scrollView)
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -1,85 +0,0 @@
//
// RxScrollViewNopDelegate.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/27/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxScrollViewNopDelegate : RxScrollViewDelegateType {
public init() {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
}
public func scrollViewDidScroll(scrollView: UIScrollView) // any offset changes
{
}
@availability(iOS, introduced=3.2)
public func scrollViewDidZoom(scrollView: UIScrollView) // any zoom scale changes
{
}
// called on start of dragging (may require some time and or distance to move)
public func scrollViewWillBeginDragging(scrollView: UIScrollView)
{
}
// called on finger up if the user dragged. velocity is in points/millisecond. targetContentOffset may be changed to adjust where the scroll view comes to rest
@availability(iOS, introduced=5.0)
public func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
{
}
// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
public func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
{
}
public func scrollViewWillBeginDecelerating(scrollView: UIScrollView) // called on finger up as we are moving
{
}
public func scrollViewDidEndDecelerating(scrollView: UIScrollView) // called when scroll view grinds to a halt
{
}
public func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) // called when setContentOffset/scrollRectVisible:animated: finishes. not called if not animating
{
}
public func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? // return a view that will be scaled. if delegate returns nil, nothing happens
{
return nil
}
@availability(iOS, introduced=3.2)
public func scrollViewWillBeginZooming(scrollView: UIScrollView, withView view: UIView!) // called before the scroll view begins zooming its content
{
}
public func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView!, atScale scale: CGFloat) // scale between minimum and maximum. called after any 'bounce' animations
{
}
public func scrollViewShouldScrollToTop(scrollView: UIScrollView) -> Bool // return a yes if you want to scroll to the top. if not defined, assumes YES
{
return true
}
public func scrollViewDidScrollToTop(scrollView: UIScrollView) // called when scrolling animation finished. may be called immediately if already at top
{
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -1,202 +0,0 @@
//
// RxTableViewDelegateConverter.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/27/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxTableViewDelegateConverter : RxScrollViewDelegateConverter
, RxTableViewDelegateType {
unowned let tableViewDelegate: UITableViewDelegate
let strongTableViewDelegate: UITableViewDelegate?
public init(delegate: UITableViewDelegate, retainDelegate: Bool) {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
self.strongTableViewDelegate = retainDelegate ? delegate : nil
self.tableViewDelegate = delegate
super.init(delegate: delegate, retainDelegate: retainDelegate)
}
// Display customization
public func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate.tableView?(tableView, willDisplayCell: cell, forRowAtIndexPath: indexPath)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
tableViewDelegate.tableView?(tableView, willDisplayHeaderView: view, forSection: section)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) {
tableViewDelegate.tableView?(tableView, willDisplayFooterView: view, forSection: section)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate.tableView?(tableView, didEndDisplayingCell: cell, forRowAtIndexPath: indexPath)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {
tableViewDelegate.tableView?(tableView, didEndDisplayingHeaderView: view, forSection: section)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingFooterView view: UIView, forSection section: Int) {
tableViewDelegate.tableView?(tableView, didEndDisplayingFooterView: view, forSection: section)
}
// Variable height support
public func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableViewDelegate.tableView?(tableView, heightForRowAtIndexPath: indexPath) ?? defaultHeight
}
public func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return tableViewDelegate.tableView?(tableView, heightForHeaderInSection: section) ?? defaultHeight
}
public func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return tableViewDelegate.tableView?(tableView, heightForFooterInSection: section) ?? defaultHeight
}
// Use the estimatedHeight methods to quickly calcuate guessed values which will allow for fast load times of the table.
// If these methods are implemented, the above -tableView:heightForXXX calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableViewDelegate.tableView?(tableView, estimatedHeightForRowAtIndexPath: indexPath) ?? defaultHeight
}
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return tableViewDelegate.tableView?(tableView, estimatedHeightForHeaderInSection: section) ?? defaultHeight
}
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat {
return tableViewDelegate.tableView?(tableView, estimatedHeightForFooterInSection: section) ?? defaultHeight
}
// Section header & footer information. Views are preferred over title should you decide to provide both
public func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? // custom view for header. will be adjusted to default or specified header height
{
return tableViewDelegate.tableView?(tableView, viewForHeaderInSection: section) ?? nil
}
public func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? // custom view for footer. will be adjusted to default or specified footer height
{
return tableViewDelegate.tableView?(tableView, viewForFooterInSection: section) ?? nil
}
// Accessories (disclosures).
public func tableView(tableView: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath)
{
tableViewDelegate.tableView?(tableView, accessoryButtonTappedForRowWithIndexPath: indexPath)
}
// Selection
// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
// Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return tableViewDelegate.tableView?(tableView, shouldHighlightRowAtIndexPath: indexPath) ?? true
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate.tableView?(tableView, didHighlightRowAtIndexPath: indexPath)
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate.tableView?(tableView, didUnhighlightRowAtIndexPath: indexPath)
}
// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
public func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
return tableViewDelegate.tableView?(tableView, willSelectRowAtIndexPath: indexPath) ?? nil
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, willDeselectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
return tableViewDelegate.tableView?(tableView, willDeselectRowAtIndexPath: indexPath) ?? nil
}
// Called after the user changes the selection.
public func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate.tableView?(tableView, didSelectRowAtIndexPath: indexPath)
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate.tableView?(tableView, didDeselectRowAtIndexPath: indexPath)
}
// Editing
// Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
public func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return tableViewDelegate.tableView?(tableView, editingStyleForRowAtIndexPath: indexPath) ?? .None
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String! {
return tableViewDelegate.tableView?(tableView, titleForDeleteConfirmationButtonForRowAtIndexPath: indexPath) ?? nil
}
@availability(iOS, introduced=8.0)
public func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? // supercedes -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil
{
return tableViewDelegate.tableView?(tableView, editActionsForRowAtIndexPath: indexPath) ?? nil
}
// Controls whether the background is indented while editing. If not implemented, the default is YES. This is unrelated to the indentation level below. This method only applies to grouped style table views.
public func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return tableViewDelegate.tableView?(tableView, shouldIndentWhileEditingRowAtIndexPath: indexPath) ?? true
}
// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
public func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate.tableView?(tableView, willBeginEditingRowAtIndexPath: indexPath)
}
public func tableView(tableView: UITableView, didEndEditingRowAtIndexPath indexPath: NSIndexPath) {
tableViewDelegate.tableView?(tableView, didEndEditingRowAtIndexPath: indexPath)
}
// Moving/reordering
// Allows customization of the target row for a particular row as it is being moved/reordered
public func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
return tableViewDelegate.tableView?(tableView, targetIndexPathForMoveFromRowAtIndexPath: sourceIndexPath, toProposedIndexPath: proposedDestinationIndexPath) ?? proposedDestinationIndexPath
}
// Indentation
public func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int // return 'depth' of row for hierarchies
{
return tableViewDelegate.tableView?(tableView, indentationLevelForRowAtIndexPath: indexPath) ?? 0
}
// Copy/Paste. All three methods must be implemented by the delegate.
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, shouldShowMenuForRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return tableViewDelegate.tableView?(tableView, shouldShowMenuForRowAtIndexPath: indexPath) ?? false
}
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, canPerformAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject) -> Bool {
return tableViewDelegate.tableView?(tableView, canPerformAction: action, forRowAtIndexPath: indexPath, withSender: sender) ?? false
}
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, performAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) {
tableViewDelegate.tableView?(tableView, performAction: action, forRowAtIndexPath: indexPath, withSender: sender)
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -1,215 +0,0 @@
//
// RxTableViewNopDelegate.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/27/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxTableViewNopDelegate : RxScrollViewNopDelegate
, RxTableViewDelegateType {
public override init() {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
#endif
super.init()
}
// Display customization
public func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) {
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didEndDisplayingFooterView view: UIView, forSection section: Int) {
}
// Variable height support
public func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return defaultHeight
}
public func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return defaultHeight
}
public func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return defaultHeight
}
// Use the estimatedHeight methods to quickly calcuate guessed values which will allow for fast load times of the table.
// If these methods are implemented, the above -tableView:heightForXXX calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return defaultHeight
}
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return defaultHeight
}
@availability(iOS, introduced=7.0)
public func tableView(tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat {
return defaultHeight
}
// Section header & footer information. Views are preferred over title should you decide to provide both
public func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? // custom view for header. will be adjusted to default or specified header height
{
return nil
}
public func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? // custom view for footer. will be adjusted to default or specified footer height
{
return nil
}
// Accessories (disclosures).
public func tableView(tableView: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath)
{
}
// Selection
// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
// Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool
{
return true
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath)
{
}
@availability(iOS, introduced=6.0)
public func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath)
{
}
// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
public func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath?
{
return nil
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, willDeselectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath?
{
return nil
}
// Called after the user changes the selection.
public func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
{
}
// Editing
// Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
public func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle
{
return .None
}
@availability(iOS, introduced=3.0)
public func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String!
{
return nil
}
@availability(iOS, introduced=8.0)
public func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? // supercedes -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil
{
return nil
}
// Controls whether the background is indented while editing. If not implemented, the default is YES. This is unrelated to the indentation level below. This method only applies to grouped style table views.
public func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool
{
return true
}
// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
public func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath)
{
}
public func tableView(tableView: UITableView, didEndEditingRowAtIndexPath indexPath: NSIndexPath)
{
}
// Moving/reordering
// Allows customization of the target row for a particular row as it is being moved/reordered
public func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath
{
return proposedDestinationIndexPath
}
// Indentation
public func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int // return 'depth' of row for hierarchies
{
return 0
}
// Copy/Paste. All three methods must be implemented by the delegate.
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, shouldShowMenuForRowAtIndexPath indexPath: NSIndexPath) -> Bool
{
return false
}
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, canPerformAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject) -> Bool
{
return false
}
@availability(iOS, introduced=5.0)
public func tableView(tableView: UITableView, performAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!)
{
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -7,21 +7,12 @@
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public protocol RxCollectionViewDataSourceType : class /* UICollectionViewDataSource */ {
// copied methods from UICollectionViewDataSource
// Please take a look at `DelegateProxyType.swift`
public protocol RxCollectionViewDataSourceType /*: UICollectionViewDataSource*/ {
typealias Element
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
// The view that is returned must be retrieved from a call to -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView
func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) -> Void
}

View File

@ -1,38 +0,0 @@
//
// RxCollectionViewDelegateType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public protocol RxCollectionViewDelegateType : RxScrollViewDelegateType {
func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool
func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath)
func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath)
func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool
func collectionView(collectionView: UICollectionView, shouldDeselectItemAtIndexPath indexPath: NSIndexPath) -> Bool // called when the user taps on an already-selected item in multi-select mode
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath)
@availability(iOS, introduced=8.0)
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath)
@availability(iOS, introduced=8.0)
func collectionView(collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, atIndexPath indexPath: NSIndexPath)
func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath)
func collectionView(collectionView: UICollectionView, didEndDisplayingSupplementaryView view: UICollectionReusableView, forElementOfKind elementKind: String, atIndexPath indexPath: NSIndexPath)
// These methods provide support for copy/paste actions on cells.
// All three should be implemented if any are.
func collectionView(collectionView: UICollectionView, shouldShowMenuForItemAtIndexPath indexPath: NSIndexPath) -> Bool
func collectionView(collectionView: UICollectionView, canPerformAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) -> Bool
func collectionView(collectionView: UICollectionView, performAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!)
// support for custom transition layout
func collectionView(collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout!
}

View File

@ -1,18 +0,0 @@
//
// RxCollectionViewReactiveDataSourceType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public protocol RxCollectionViewReactiveDataSourceType : RxCollectionViewDataSourceType {
typealias Element
func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) -> Void
}

View File

@ -1,41 +0,0 @@
//
// RxScrollViewDelegateType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/26/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
// Please take a look at `DelegateBridgeType.swift`
public protocol RxScrollViewDelegateType : class /*, UIScrollViewDelegate */ {
func scrollViewDidScroll(scrollView: UIScrollView) // any offset changes
@availability(iOS, introduced=3.2)
func scrollViewDidZoom(scrollView: UIScrollView) // any zoom scale changes
// called on start of dragging (may require some time and or distance to move)
func scrollViewWillBeginDragging(scrollView: UIScrollView)
// called on finger up if the user dragged. velocity is in points/millisecond. targetContentOffset may be changed to adjust where the scroll view comes to rest
@availability(iOS, introduced=5.0)
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
func scrollViewWillBeginDecelerating(scrollView: UIScrollView) // called on finger up as we are moving
func scrollViewDidEndDecelerating(scrollView: UIScrollView) // called when scroll view grinds to a halt
func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) // called when setContentOffset/scrollRectVisible:animated: finishes. not called if not animating
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? // return a view that will be scaled. if delegate returns nil, nothing happens
@availability(iOS, introduced=3.2)
func scrollViewWillBeginZooming(scrollView: UIScrollView, withView view: UIView!) // called before the scroll view begins zooming its content
func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView!, atScale scale: CGFloat) // scale between minimum and maximum. called after any 'bounce' animations
func scrollViewShouldScrollToTop(scrollView: UIScrollView) -> Bool // return a yes if you want to scroll to the top. if not defined, assumes YES
func scrollViewDidScrollToTop(scrollView: UIScrollView) // called when scrolling animation finished. may be called immediately if already at top
}

View File

@ -2,7 +2,7 @@
// RxTableViewDataSourceType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/25/15.
// Created by Krunoslav Zaher on 6/26/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
@ -10,44 +10,9 @@ import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public protocol RxTableViewDataSourceType : class /* UITableViewDataSource*/ {
// copied methods from UITableViewDataSource
// Please take a look at `DelegateProxyType.swift`
public protocol RxTableViewDataSourceType /*: UITableViewDataSource*/ {
typealias Element
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
func numberOfSectionsInTableView(tableView: UITableView) -> Int // Default is 1 if not implemented
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? // fixed font style. use custom view (UILabel) if you want something different
func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String?
// Editing
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
// Moving/reordering
// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool
// Index
func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! // return list of section titles to display in section index view (e.g. "ABCD...Z#")
func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int // tell table which section corresponds to section title/index (e.g. "B",1))
// Data manipulation - insert and delete support
// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
// Data manipulation - reorder / moving support
func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)
func tableView(tableView: UITableView, observedEvent: Event<Element>) -> Void
}

View File

@ -1,107 +0,0 @@
//
// RxTableViewDelegateType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/26/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public protocol RxTableViewDelegateType : RxScrollViewDelegateType {
// Display customization
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
@availability(iOS, introduced=6.0)
func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
@availability(iOS, introduced=6.0)
func tableView(tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int)
@availability(iOS, introduced=6.0)
func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
@availability(iOS, introduced=6.0)
func tableView(tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int)
@availability(iOS, introduced=6.0)
func tableView(tableView: UITableView, didEndDisplayingFooterView view: UIView, forSection section: Int)
// Variable height support
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
// Use the estimatedHeight methods to quickly calcuate guessed values which will allow for fast load times of the table.
// If these methods are implemented, the above -tableView:heightForXXX calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.
@availability(iOS, introduced=7.0)
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
@availability(iOS, introduced=7.0)
func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat
@availability(iOS, introduced=7.0)
func tableView(tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat
// Section header & footer information. Views are preferred over title should you decide to provide both
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? // custom view for header. will be adjusted to default or specified header height
func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? // custom view for footer. will be adjusted to default or specified footer height
// Accessories (disclosures).
func tableView(tableView: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath)
// Selection
// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
// Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
@availability(iOS, introduced=6.0)
func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool
@availability(iOS, introduced=6.0)
func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath)
@availability(iOS, introduced=6.0)
func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath)
// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath?
@availability(iOS, introduced=3.0)
func tableView(tableView: UITableView, willDeselectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath?
// Called after the user changes the selection.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
@availability(iOS, introduced=3.0)
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
// Editing
// Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle
@availability(iOS, introduced=3.0)
func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String!
@availability(iOS, introduced=8.0)
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? // supercedes -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil
// Controls whether the background is indented while editing. If not implemented, the default is YES. This is unrelated to the indentation level below. This method only applies to grouped style table views.
func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool
// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath)
func tableView(tableView: UITableView, didEndEditingRowAtIndexPath indexPath: NSIndexPath)
// Moving/reordering
// Allows customization of the target row for a particular row as it is being moved/reordered
func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath
// Indentation
func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int // return 'depth' of row for hierarchies
// Copy/Paste. All three methods must be implemented by the delegate.
@availability(iOS, introduced=5.0)
func tableView(tableView: UITableView, shouldShowMenuForRowAtIndexPath indexPath: NSIndexPath) -> Bool
@availability(iOS, introduced=5.0)
func tableView(tableView: UITableView, canPerformAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject) -> Bool
@availability(iOS, introduced=5.0)
func tableView(tableView: UITableView, performAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!)
}

View File

@ -1,18 +0,0 @@
//
// RxTableViewReactiveDataSourceType.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/26/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public protocol RxTableViewReactiveDataSourceType : RxTableViewDataSourceType {
typealias Element
func tableView(tableView: UITableView, observedEvent: Event<Element>) -> Void
}

View File

@ -1,5 +1,5 @@
//
// RxCollectionViewDataSourceBridge.swift
// RxCollectionViewDataSourceProxy.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
@ -10,13 +10,14 @@ import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxCollectionViewDataSourceBridge : Delegate
, UICollectionViewDataSource
, DelegateBridgeType {
// Please take a look at `DelegateProxyType.swift`
public class RxCollectionViewDataSourceProxy : Delegate
, UICollectionViewDataSource
, DelegateProxyType {
public let collectionView: UICollectionView
var dataSource: RxCollectionViewDataSourceType?
var dataSource: UICollectionViewDataSource?
public init(view: UICollectionView) {
self.collectionView = view
@ -35,30 +36,29 @@ public class RxCollectionViewDataSourceBridge : Delegate
}
public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return dataSource?.numberOfSectionsInCollectionView(collectionView) ?? 1
return dataSource?.numberOfSectionsInCollectionView?(collectionView) ?? 0
}
// The view that is returned must be retrieved from a call to -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
public func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
return dataSource!.collectionView(collectionView, viewForSupplementaryElementOfKind: kind, atIndexPath: indexPath)
return dataSource!.collectionView!(collectionView, viewForSupplementaryElementOfKind: kind, atIndexPath: indexPath)
}
// bridge
// proxy
public class func createBridgeForView(view: UIView) -> Self {
public class func createProxyForView(view: UIView) -> Self {
let collectionView = view as! UICollectionView
return castOrFatalError(collectionView.rx_createDataSourceBridge())
return castOrFatalError(collectionView.rx_createDataSourceProxy())
}
public class func getBridgeForView(view: UIView) -> Self? {
public class func getProxyForView(view: UIView) -> Self? {
let collectionView = view as! UICollectionView
return castOptionalOrFatalError(collectionView.dataSource)
}
// tried using `Self` instead of Any object, didn't work out
public class func setBridgeToView(view: UIView, bridge: AnyObject) {
public class func setProxyToView(view: UIView, proxy: AnyObject) {
let collectionView = view as! UICollectionView
collectionView.dataSource = castOptionalOrFatalError(bridge)
collectionView.dataSource = castOptionalOrFatalError(proxy)
}
public func setDelegate(delegate: AnyObject?) {
@ -69,6 +69,9 @@ public class RxCollectionViewDataSourceBridge : Delegate
return dataSource
}
override public func respondsToSelector(aSelector: Selector) -> Bool {
return super.respondsToSelector(aSelector)// || (self.dataSource?.respondsToSelector(aSelector) ?? false)
}
// disposable

View File

@ -0,0 +1,70 @@
//
// RxCollectionViewDelegateProxy.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/29/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateProxyType.swift`
public class RxCollectionViewDelegateProxy : RxScrollViewDelegateProxy
, UICollectionViewDelegate {
public typealias ItemSelectedObserver = ObserverOf<ItemSelectedEvent<UICollectionView>>
public typealias ItemSelectedDisposeKey = Bag<ItemSelectedObserver>.KeyType
public let collectionView: UICollectionView
var itemSelectedObservers: Bag<ItemSelectedObserver> = Bag()
var collectionViewDelegate: UICollectionViewDelegate?
public override init(view: UIView) {
self.collectionView = view as! UICollectionView
super.init(view: view)
}
public func addItemSelectedObserver(observer: ItemSelectedObserver) -> ItemSelectedDisposeKey {
return itemSelectedObservers.put(observer)
}
public func removeItemSelectedObserver(key: ItemSelectedDisposeKey) {
let element = itemSelectedObservers.removeKey(key)
if element == nil {
removingObserverFailed()
}
}
// delegate proxy
override public class func setProxyToView(view: UIView, proxy: AnyObject) {
let _: UICollectionViewDelegate = castOrFatalError(proxy)
super.setProxyToView(view, proxy: proxy)
}
override public func setDelegate(delegate: AnyObject?) {
let typedDelegate: UICollectionViewDelegate? = castOptionalOrFatalError(delegate)
self.collectionViewDelegate = typedDelegate
super.setDelegate(delegate)
}
// dispose
public override var isDisposable: Bool {
get {
return super.isDisposable && self.itemSelectedObservers.count == 0
}
}
deinit {
if !isDisposable {
handleVoidObserverResult(failure(rxError(RxCocoaError.InvalidOperation, "Something went wrong. Deallocating collection view delegate while there are still subscribed observers means that some subscription was left undisposed.")))
}
}
}

View File

@ -1,5 +1,5 @@
//
// RxScrollViewDelegateBridge.swift
// RxScrollViewDelegateProxy.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/19/15.
@ -10,10 +10,10 @@ import Foundation
import RxSwift
import UIKit
// Please take a look at `DelegateBridgeType.swift`
public class RxScrollViewDelegateBridge : Delegate
, UIScrollViewDelegate
, DelegateBridgeType {
// Please take a look at `DelegateProxyType.swift`
public class RxScrollViewDelegateProxy : Delegate
, UIScrollViewDelegate
, DelegateProxyType {
public typealias ContentOffsetObserver = ObserverOf<CGPoint>
public typealias ContentOffsetDisposeKey = Bag<ContentOffsetObserver>.KeyType
@ -29,7 +29,7 @@ public class RxScrollViewDelegateBridge : Delegate
let scrollView: UIScrollView
var scrollViewDelegate: RxScrollViewDelegateType? = nil
var scrollViewDelegate: UIScrollViewDelegate? = nil
public init(view: UIView) {
contentOffsetObservers = Bag()
@ -93,22 +93,22 @@ public class RxScrollViewDelegateBridge : Delegate
public func scrollViewDidScroll(scrollView: UIScrollView) {
dispatchNext(scrollView.contentOffset, contentOffsetObservers)
scrollViewDelegate?.scrollViewDidScroll(scrollView)
scrollViewDelegate?.scrollViewDidScroll?(scrollView)
}
public func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
dispatchNext((), willBeginDeceleratingObservers)
scrollViewDelegate?.scrollViewWillBeginDecelerating(scrollView)
scrollViewDelegate?.scrollViewWillBeginDecelerating?(scrollView)
}
public func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
dispatchNext((), didEndDeceleratingObservers)
scrollViewDelegate?.scrollViewDidEndDecelerating(scrollView)
scrollViewDelegate?.scrollViewDidEndDecelerating?(scrollView)
}
// delegate bridge
// delegate proxy
public class func getBridgeForView(view: UIView) -> Self? {
public class func getProxyForView(view: UIView) -> Self? {
MainScheduler.ensureExecutingOnScheduler()
let scrollView = view as! UIScrollView
@ -120,17 +120,17 @@ public class RxScrollViewDelegateBridge : Delegate
return castOptionalOrFatalError(scrollView.delegate)
}
public class func setBridgeToView(view: UIView, bridge: AnyObject) {
public class func setProxyToView(view: UIView, proxy: AnyObject) {
let scrollView = view as! UIScrollView
let delegate: UIScrollViewDelegate = castOrFatalError(bridge)
let delegate: UIScrollViewDelegate = castOrFatalError(proxy)
scrollView.delegate = delegate
}
public class func createBridgeForView(view: UIView) -> Self {
public class func createProxyForView(view: UIView) -> Self {
let scrollView = view as! UIScrollView
return castOrFatalError(scrollView.rx_createDelegateBridge())
return castOrFatalError(scrollView.rx_createDelegateProxy())
}
public func setDelegate(delegate: AnyObject?) {
@ -147,6 +147,14 @@ public class RxScrollViewDelegateBridge : Delegate
return self.scrollViewDelegate
}
override public func forwardingTargetForSelector(aSelector: Selector) -> AnyObject? {
return self.scrollViewDelegate
}
override public func respondsToSelector(aSelector: Selector) -> Bool {
return super.respondsToSelector(aSelector) || (self.scrollViewDelegate?.respondsToSelector(aSelector) ?? false)
}
// dispose
override public func dispose() {

View File

@ -1,5 +1,5 @@
//
// RxTableViewDataSourceBridge.swift
// RxTableViewDataSourceProxy.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/15/15.
@ -10,10 +10,10 @@ import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateBridgeType.swift`
public class RxTableViewDataSourceBridge : Delegate
, UITableViewDataSource
, DelegateBridgeType {
// Please take a look at `DelegateProxyType.swift`
public class RxTableViewDataSourceProxy : Delegate
, UITableViewDataSource
, DelegateProxyType {
public typealias InsertItemObserver = ObserverOf<InsertItemEvent<UITableView>>
public typealias DeleteItemObserver = ObserverOf<DeleteItemEvent<UITableView>>
@ -29,7 +29,7 @@ public class RxTableViewDataSourceBridge : Delegate
public let tableView: UITableView
var dataSource: RxTableViewDataSourceType?
var dataSource: UITableViewDataSource?
public init(view: UITableView) {
self.tableView = view
@ -116,68 +116,34 @@ public class RxTableViewDataSourceBridge : Delegate
// data source delegate
public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.dataSource!.numberOfSectionsInTableView?(tableView) ?? 1
}
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataSource?.tableView(tableView, numberOfRowsInSection: section) ?? 0
return self.dataSource!.tableView(tableView, numberOfRowsInSection: section)
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return self.dataSource!.tableView(tableView, cellForRowAtIndexPath: indexPath)
}
public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.dataSource?.numberOfSectionsInTableView(tableView) ?? 1
}
// proxy
public func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.dataSource?.tableView(tableView, titleForHeaderInSection: section)
}
public func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return self.dataSource?.tableView(tableView, titleForFooterInSection: section)
}
public func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return self.dataSource?.tableView(tableView, canEditRowAtIndexPath: indexPath) ?? false
}
public func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return self.dataSource?.tableView(tableView, canMoveRowAtIndexPath: indexPath) ?? false
}
public func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! {
return self.dataSource?.sectionIndexTitlesForTableView(tableView)
}
public func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return self.dataSource?.tableView(tableView, sectionForSectionIndexTitle: title, atIndex: index) ?? 0
}
public func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
commitEditingStyle(editingStyle, forRowAtIndexPath: indexPath)
self.dataSource?.tableView(tableView, commitEditingStyle: editingStyle, forRowAtIndexPath: indexPath)
}
public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
moveRowAtIndexPath(sourceIndexPath, toIndexPath: destinationIndexPath)
self.dataSource?.tableView(tableView, moveRowAtIndexPath: sourceIndexPath, toIndexPath: destinationIndexPath)
}
// bridge
public class func createBridgeForView(view: UIView) -> Self {
public class func createProxyForView(view: UIView) -> Self {
let tableView = view as! UITableView
return castOrFatalError(tableView.rx_createDataSourceBridge())
return castOrFatalError(tableView.rx_createDataSourceProxy())
}
public class func getBridgeForView(view: UIView) -> Self? {
public class func getProxyForView(view: UIView) -> Self? {
let tableView = view as! UITableView
return castOptionalOrFatalError(tableView.dataSource)
}
// tried using `Self` instead of Any object, didn't work out
public class func setBridgeToView(view: UIView, bridge: AnyObject) {
public class func setProxyToView(view: UIView, proxy: AnyObject) {
let tableView = view as! UITableView
tableView.dataSource = castOptionalOrFatalError(bridge)
tableView.dataSource = castOptionalOrFatalError(proxy)
}
public func setDelegate(delegate: AnyObject?) {
@ -188,6 +154,13 @@ public class RxTableViewDataSourceBridge : Delegate
return dataSource
}
override public func forwardingTargetForSelector(aSelector: Selector) -> AnyObject? {
return dataSource
}
override public func respondsToSelector(aSelector: Selector) -> Bool {
return super.respondsToSelector(aSelector) || (self.dataSource?.respondsToSelector(aSelector) ?? false)
}
// disposable

View File

@ -0,0 +1,69 @@
//
// RxTableViewDelegateProxy.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 6/15/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// Please take a look at `DelegateProxyType.swift`
public class RxTableViewDelegateProxy : RxScrollViewDelegateProxy
, UITableViewDelegate {
public typealias ItemSelectedObserver = ObserverOf<ItemSelectedEvent<UITableView>>
public typealias ItemSelectedDisposeKey = Bag<ItemSelectedObserver>.KeyType
public let tableView: UITableView
var itemSelectedObservers: Bag<ItemSelectedObserver> = Bag()
var tableViewDelegate: UITableViewDelegate?
public override init(view: UIView) {
self.tableView = view as! UITableView
super.init(view: view)
}
public func addItemSelectedObserver(observer: ItemSelectedObserver) -> ItemSelectedDisposeKey {
return itemSelectedObservers.put(observer)
}
public func removeItemSelectedObserver(key: ItemSelectedDisposeKey) {
let element = itemSelectedObservers.removeKey(key)
if element == nil {
removingObserverFailed()
}
}
// delegate proxy
override public class func setProxyToView(view: UIView, proxy: AnyObject) {
let _: UITableViewDelegate = castOrFatalError(proxy)
super.setProxyToView(view, proxy: proxy)
}
override public func setDelegate(delegate: AnyObject?) {
let typedDelegate: UITableViewDelegate? = castOptionalOrFatalError(delegate)
self.tableViewDelegate = typedDelegate
super.setDelegate(delegate)
}
// dispose
public override var isDisposable: Bool {
get {
return super.isDisposable && self.itemSelectedObservers.count == 0
}
}
deinit {
if !isDisposable {
handleVoidObserverResult(failure(rxError(RxCocoaError.InvalidOperation, "Something went wrong. Deallocating table view delegate while there are still subscribed observers means that some subscription was left undisposed.")))
}
}
}

View File

@ -15,12 +15,12 @@ extension UICollectionView {
// factories
override public func rx_createDelegateBridge() -> RxScrollViewDelegateBridge {
return RxCollectionViewDelegateBridge(view: self)
override public func rx_createDelegateProxy() -> RxScrollViewDelegateProxy {
return RxCollectionViewDelegateProxy(view: self)
}
public func rx_createDataSourceBridge() -> RxCollectionViewDataSourceBridge {
return RxCollectionViewDataSourceBridge(view: self)
public func rx_createDataSourceProxy() -> RxCollectionViewDataSourceProxy {
return RxCollectionViewDataSourceProxy(view: self)
}
// data source
@ -34,48 +34,29 @@ extension UICollectionView {
// ```
//
// If you want to register non reactive data source, please use `rx_setDataSource` method
public func rx_subscribeWithReactiveDataSource<DataSource: RxCollectionViewReactiveDataSourceType>
public func rx_subscribeWithReactiveDataSource<DataSource: protocol<RxCollectionViewDataSourceType, UICollectionViewDataSource>>
(dataSource: DataSource)
-> Observable<DataSource.Element> -> Disposable {
return subscribeObservableUsingDelegateBridgeAndDataSource(self, dataSource, { (_: RxCollectionViewDataSourceBridge, event) -> Void in
return subscribeObservableUsingDelegateProxyAndDataSource(self, dataSource, { (_: RxCollectionViewDataSourceProxy, event) -> Void in
dataSource.collectionView(self, observedEvent: event)
})
}
// Registers `RxCollectionViewDataSourceType`.
// For more detailed explanations, take a look at `RxCollectionViewDataSourceType.swift` and `DelegateBridgeType.swift`
public func rx_setDataSource(dataSource: RxCollectionViewDataSourceType)
-> Disposable {
let result: BridgeDisposablePair<RxCollectionViewDataSourceBridge> = installDelegateOnBridge(self, dataSource)
return result.disposable
}
// Registers `UICollectionViewDataSource`.
// For more detailed explanations, take a look at `RxCollectionViewDataSourceType.swift` and `DelegateBridgeType.swift`
// For more detailed explanations, take a look at `RxCollectionViewDataSourceType.swift` and `DelegateProxyType.swift`
public func rx_setDataSource(dataSource: UICollectionViewDataSource, retainDataSource: Bool)
-> Disposable {
let converter = RxCollectionViewDataSourceConverter(dataSource: dataSource, retainDataSource: retainDataSource)
let result: BridgeDisposablePair<RxCollectionViewDataSourceBridge> = installDelegateOnBridge(self, dataSource)
let result: ProxyDisposablePair<RxCollectionViewDataSourceProxy> = installDelegateOnProxy(self, dataSource)
return result.disposable
}
// delegate
// For more detailed explanations, take a look at `DelegateBridgeType.swift`
// Retains delegate
public func rx_setDelegate(delegate: RxCollectionViewDelegateType) -> Disposable {
let result: BridgeDisposablePair<RxCollectionViewDelegateBridge> = installDelegateOnBridge(self, delegate)
return result.disposable
}
// For more detailed explanations, take a look at `DelegateBridgeType.swift`
// For more detailed explanations, take a look at `DelegateProxyType.swift`
public func rx_setDelegate(delegate: UICollectionViewDelegate, retainDelegate: Bool)
-> Disposable {
let converter = RxCollectionViewDelegateConverter(delegate: delegate, retainDelegate: retainDelegate)
let result: BridgeDisposablePair<RxCollectionViewDelegateBridge> = installDelegateOnBridge(self, converter)
let result: ProxyDisposablePair<RxCollectionViewDelegateProxy> = installDelegateOnProxy(self, delegate)
return result.disposable
}
@ -121,9 +102,9 @@ extension UICollectionView {
return rx_selectedItem() >- map { e in
let indexPath = e.indexPath
let bridge = RxCollectionViewDataSourceBridge.getBridgeForView(self)!
let proxy = RxCollectionViewDataSourceProxy.getProxyForView(self)!
let dataSource: RxCollectionViewReactiveArrayDataSource<T> = castOrFatalError(bridge.getDelegate())
let dataSource: RxCollectionViewReactiveArrayDataSource<T> = castOrFatalError(proxy.getDelegate())
return dataSource.modelAtIndex(indexPath.item)!
}
@ -131,13 +112,13 @@ extension UICollectionView {
// private methods
private func createDelegateObservable<E, DisposeKey>(addObserver: (RxCollectionViewDelegateBridge, ObserverOf<E>) -> DisposeKey, removeObserver: (RxCollectionViewDelegateBridge, DisposeKey) -> Void) -> Observable<E> {
return createObservableUsingDelegateBridge(self, addObserver, removeObserver)
private func createDelegateObservable<E, DisposeKey>(addObserver: (RxCollectionViewDelegateProxy, ObserverOf<E>) -> DisposeKey, removeObserver: (RxCollectionViewDelegateProxy, DisposeKey) -> Void) -> Observable<E> {
return createObservableUsingDelegateProxy(self, addObserver, removeObserver)
}
private func createDataSourceObservable<E, DisposeKey>(addObserver: (RxCollectionViewDataSourceBridge, ObserverOf<E>) -> DisposeKey,
removeObserver: (RxCollectionViewDataSourceBridge, DisposeKey) -> Void)
private func createDataSourceObservable<E, DisposeKey>(addObserver: (RxCollectionViewDataSourceProxy, ObserverOf<E>) -> DisposeKey,
removeObserver: (RxCollectionViewDataSourceProxy, DisposeKey) -> Void)
-> Observable<E> {
return createObservableUsingDelegateBridge(self, addObserver, removeObserver)
return createObservableUsingDelegateProxy(self, addObserver, removeObserver)
}
}

View File

@ -11,13 +11,13 @@ import RxSwift
import UIKit
extension UIScrollView {
public func rx_createDelegateBridge() -> RxScrollViewDelegateBridge {
return RxScrollViewDelegateBridge(view: self)
public func rx_createDelegateProxy() -> RxScrollViewDelegateProxy {
return RxScrollViewDelegateProxy(view: self)
}
public var rx_contentOffset: Observable<CGPoint> {
return createObservableUsingDelegateBridge(self, { (b: RxScrollViewDelegateBridge, o) in
return createObservableUsingDelegateProxy(self, { (b: RxScrollViewDelegateProxy, o) in
return b.addContentOffsetObserver(o)
}, { (b, d) -> () in
b.removeContentOffsetObserver(d)
@ -25,20 +25,11 @@ extension UIScrollView {
}
// delegate
// For more detailed explanations, take a look at `DelegateBridgeType.swift`
// Retains delegate
public func rx_setDelegate(delegate: RxScrollViewDelegateType) -> Disposable {
let result: BridgeDisposablePair<RxScrollViewDelegateBridge> = installDelegateOnBridge(self, delegate)
return result.disposable
}
// For more detailed explanations, take a look at `DelegateBridgeType.swift`
// For more detailed explanations, take a look at `DelegateProxyType.swift`
public func rx_setDelegate(delegate: UIScrollViewDelegate, retainDelegate: Bool)
-> Disposable {
let converter = RxScrollViewDelegateConverter(delegate: delegate, retainDelegate: retainDelegate)
let result: BridgeDisposablePair<RxScrollViewDelegateBridge> = installDelegateOnBridge(self, converter)
let result: ProxyDisposablePair<RxScrollViewDelegateProxy> = installDelegateOnProxy(self, delegate)
return result.disposable
}

View File

@ -14,12 +14,12 @@ extension UITableView {
// factories
public func rx_createDataSourceBridge() -> RxTableViewDataSourceBridge {
return RxTableViewDataSourceBridge(view: self)
public func rx_createDataSourceProxy() -> RxTableViewDataSourceProxy {
return RxTableViewDataSourceProxy(view: self)
}
public override func rx_createDelegateBridge() -> RxScrollViewDelegateBridge {
return RxTableViewDelegateBridgeWithProxyFiltering(view: self)
public override func rx_createDelegateProxy() -> RxScrollViewDelegateProxy {
return RxTableViewDelegateProxy(view: self)
}
@ -34,48 +34,29 @@ extension UITableView {
// ```
//
// If you want to register non reactive data source, please use `rx_setDataSource` method
public func rx_subscribeWithReactiveDataSource<DataSource: RxTableViewReactiveDataSourceType>
public func rx_subscribeWithReactiveDataSource<DataSource: protocol<RxTableViewDataSourceType, UITableViewDataSource>>
(dataSource: DataSource)
-> Observable<DataSource.Element> -> Disposable {
return subscribeObservableUsingDelegateBridgeAndDataSource(self, dataSource, { (_: RxTableViewDataSourceBridge, event) -> Void in
return subscribeObservableUsingDelegateProxyAndDataSource(self, dataSource, { (_: RxTableViewDataSourceProxy, event) -> Void in
dataSource.tableView(self, observedEvent: event)
})
}
// Registers `RxTableViewDataSourceType`.
// For more detailed explanations, take a look at `RxTableViewDataSourceType.swift` and `DelegateBridgeType.swift`
public func rx_setDataSource(dataSource: RxTableViewDataSourceType)
-> Disposable {
let result: BridgeDisposablePair<RxTableViewDataSourceBridge> = installDelegateOnBridge(self, dataSource)
return result.disposable
}
// Registers `UITableViewDataSource`.
// For more detailed explanations, take a look at `RxTableViewDataSourceType.swift` and `DelegateBridgeType.swift`
// For more detailed explanations, take a look at `RxTableViewDataSourceType.swift` and `DelegateProxyType.swift`
public func rx_setDataSource(dataSource: UITableViewDataSource, retainDataSource: Bool)
-> Disposable {
let converter = RxTableViewDataSourceConverter(dataSource: dataSource, retainDataSource: retainDataSource)
let result: BridgeDisposablePair<RxTableViewDataSourceBridge> = installDelegateOnBridge(self, dataSource)
let result: ProxyDisposablePair<RxTableViewDataSourceProxy> = installDelegateOnProxy(self, dataSource)
return result.disposable
}
// delegate
// For more detailed explanations, take a look at `DelegateBridgeType.swift`
// Retains delegate
public func rx_setDelegate(delegate: RxTableViewDelegateType) -> Disposable {
let result: BridgeDisposablePair<RxTableViewDelegateBridge> = installDelegateOnBridge(self, delegate)
return result.disposable
}
// For more detailed explanations, take a look at `DelegateBridgeType.swift`
// For more detailed explanations, take a look at `DelegateProxyType.swift`
public func rx_setDelegate(delegate: UITableViewDelegate, retainDelegate: Bool)
-> Disposable {
let converter = RxTableViewDelegateConverter(delegate: delegate, retainDelegate: retainDelegate)
let result: BridgeDisposablePair<RxTableViewDelegateBridge> = installDelegateOnBridge(self, converter)
let result: ProxyDisposablePair<RxTableViewDelegateProxy> = installDelegateOnProxy(self, delegate)
return result.disposable
}
@ -138,9 +119,9 @@ extension UITableView {
return rx_selectedItem() >- map { e in
let indexPath = e.indexPath
let bridge = RxTableViewDataSourceBridge.getBridgeForView(self)!
let proxy = RxTableViewDataSourceProxy.getProxyForView(self)!
let dataSource: RxTableViewReactiveArrayDataSource<T> = castOrFatalError(bridge.getDelegate())
let dataSource: RxTableViewReactiveArrayDataSource<T> = castOrFatalError(proxy.getDelegate())
return dataSource.modelAtIndex(indexPath.item)!
}
@ -148,13 +129,13 @@ extension UITableView {
// private methods
private func createDelegateObservable<E, DisposeKey>(addObserver: (RxTableViewDelegateBridge, ObserverOf<E>) -> DisposeKey, removeObserver: (RxTableViewDelegateBridge, DisposeKey) -> Void) -> Observable<E> {
return createObservableUsingDelegateBridge(self, addObserver, removeObserver)
private func createDelegateObservable<E, DisposeKey>(addObserver: (RxTableViewDelegateProxy, ObserverOf<E>) -> DisposeKey, removeObserver: (RxTableViewDelegateProxy, DisposeKey) -> Void) -> Observable<E> {
return createObservableUsingDelegateProxy(self, addObserver, removeObserver)
}
private func createDataSourceObservable<E, DisposeKey>(addObserver: (RxTableViewDataSourceBridge, ObserverOf<E>) -> DisposeKey,
removeObserver: (RxTableViewDataSourceBridge, DisposeKey) -> Void)
private func createDataSourceObservable<E, DisposeKey>(addObserver: (RxTableViewDataSourceProxy, ObserverOf<E>) -> DisposeKey,
removeObserver: (RxTableViewDataSourceProxy, DisposeKey) -> Void)
-> Observable<E> {
return createObservableUsingDelegateBridge(self, addObserver, removeObserver)
return createObservableUsingDelegateProxy(self, addObserver, removeObserver)
}
}

View File

@ -11,15 +11,26 @@ import UIKit
import RxSwift
import RxCocoa
class RxCollectionViewSectionedAnimatedDataSource<S: SectionModelType> : RxCollectionViewSectionedDataSource<S>, RxCollectionViewReactiveDataSourceType {
class RxCollectionViewSectionedAnimatedDataSource<S: SectionModelType> : RxCollectionViewSectionedDataSource<S>
, RxCollectionViewDataSourceType {
typealias Element = [Changeset<S>]
// For some inexplicable reason, when doing animated updates first time
// it crashes. Still need to figure out that one.
var set = false
func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) {
switch observedEvent {
case .Next(let boxedSections):
for c in boxedSections.value {
//println("Animating ==============================\n\(c)\n===============================\n")
setSections(c.finalSections)
if !set {
collectionView.reloadData()
set = true
return
}
collectionView.performBatchUpdates(c)
}
case .Error(let error):

View File

@ -11,12 +11,47 @@ import UIKit
import RxSwift
import RxCocoa
public class RxCollectionViewSectionedDataSource<S: SectionModelType> : RxCollectionViewNopDataSource, RxCollectionViewDataSourceType {
public class _RxCollectionViewSectionedDataSource : NSObject
, UICollectionViewDataSource {
func _numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 0
}
public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return _numberOfSectionsInCollectionView(collectionView)
}
func _collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 0
}
public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return _collectionView(collectionView, numberOfItemsInSection: section)
}
func _collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return (nil as UICollectionViewCell?)!
}
public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return _collectionView(collectionView, cellForItemAtIndexPath: indexPath)
}
func _collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
return (nil as UICollectionReusableView?)!
}
public func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
return _collectionView(collectionView, viewForSupplementaryElementOfKind: kind, atIndexPath: indexPath)
}
}
public class RxCollectionViewSectionedDataSource<S: SectionModelType> : _RxCollectionViewSectionedDataSource {
public typealias I = S.Item
public typealias Section = S
public typealias CellFactory = (UICollectionView, NSIndexPath, Section, I) -> UICollectionViewCell
public typealias SupplementaryViewFactory = (UICollectionView, String, NSIndexPath, I) -> UICollectionReusableView
public typealias CellFactory = (UICollectionView, NSIndexPath, I) -> UICollectionViewCell
public typealias SupplementaryViewFactory = (UICollectionView, String, NSIndexPath) -> UICollectionReusableView
public typealias IncrementalUpdateObserver = ObserverOf<Changeset<S>>
@ -35,6 +70,10 @@ public class RxCollectionViewSectionedDataSource<S: SectionModelType> : RxCollec
public func sectionAtIndex(section: Int) -> S {
return self.sectionModels[section].model
}
public func itemAtIndexPath(indexPath: NSIndexPath) -> I {
return self.sectionModels[indexPath.section].items[indexPath.item]
}
var incrementalUpdateObservers: Bag<IncrementalUpdateObserver> = Bag()
@ -46,8 +85,8 @@ public class RxCollectionViewSectionedDataSource<S: SectionModelType> : RxCollec
public var supplementaryViewFactory: SupplementaryViewFactory
public override init() {
self.cellFactory = { _, _, _, _ in castOrFail(nil).get() }
self.supplementaryViewFactory = { _, _, _, _ in castOrFail(nil).get() }
self.cellFactory = { _, _, _ in castOrFail(nil).get() }
self.supplementaryViewFactory = { _, _, _ in castOrFail(nil).get() }
super.init()
self.cellFactory = { [weak self] _ in
@ -56,7 +95,7 @@ public class RxCollectionViewSectionedDataSource<S: SectionModelType> : RxCollec
return (nil as UICollectionViewCell!)!
}
self.supplementaryViewFactory = { [weak self] _, _, _, _ in
self.supplementaryViewFactory = { [weak self] _, _, _ in
precondition(false, "There is a minor problem. `supplementaryViewFactory` property on \(self!) was not set.")
return (nil as UICollectionReusableView?)!
}
@ -75,23 +114,21 @@ public class RxCollectionViewSectionedDataSource<S: SectionModelType> : RxCollec
// UITableViewDataSource
public override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
override func _numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return sectionModels.count
}
public override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
override func _collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return sectionModels[section].items.count
}
public override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
override func _collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
precondition(indexPath.item < sectionModels[indexPath.section].items.count)
let item = indexPath.item
let section = sectionModels[indexPath.section]
return cellFactory(collectionView, indexPath, section.model, section.items[item])
return cellFactory(collectionView, indexPath, itemAtIndexPath(indexPath))
}
public func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
return supplementaryViewFactory(collectionView, kind, indexPath, sectionModels[indexPath.section].items[indexPath.item])
override func _collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
return supplementaryViewFactory(collectionView, kind, indexPath)
}
}

View File

@ -11,7 +11,8 @@ import UIKit
import RxSwift
import RxCocoa
class RxCollectionViewSectionedReloadDataSource<S: SectionModelType> : RxCollectionViewSectionedDataSource<S>, RxCollectionViewReactiveDataSourceType {
class RxCollectionViewSectionedReloadDataSource<S: SectionModelType> : RxCollectionViewSectionedDataSource<S>
, RxCollectionViewDataSourceType {
typealias Element = [S]
func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) {

View File

@ -11,7 +11,8 @@ import UIKit
import RxSwift
import RxCocoa
class RxTableViewSectionedAnimatedDataSource<S: SectionModelType> : RxTableViewSectionedDataSource<S>, RxTableViewReactiveDataSourceType {
class RxTableViewSectionedAnimatedDataSource<S: SectionModelType> : RxTableViewSectionedDataSource<S>
, RxTableViewDataSourceType {
typealias Element = [Changeset<S>]
func tableView(tableView: UITableView, observedEvent: Event<Element>) {

View File

@ -11,7 +11,52 @@ import RxSwift
import RxCocoa
import UIKit
public class RxTableViewSectionedDataSource<S: SectionModelType> : RxTableViewNopDataSource {
// objc monkey business
public class _RxTableViewSectionedDataSource : NSObject
, UITableViewDataSource {
func _numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return _numberOfSectionsInTableView(tableView)
}
func _tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return _tableView(tableView, numberOfRowsInSection: section)
}
func _tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return (nil as UITableViewCell?)!
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return _tableView(tableView, cellForRowAtIndexPath: indexPath)
}
func _tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return nil
}
public func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return _tableView(tableView, titleForHeaderInSection: section)
}
func _tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return nil
}
public func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return _tableView(tableView, titleForFooterInSection: section)
}
}
public class RxTableViewSectionedDataSource<S: SectionModelType> : _RxTableViewSectionedDataSource {
public typealias I = S.Item
public typealias Section = S
@ -72,15 +117,15 @@ public class RxTableViewSectionedDataSource<S: SectionModelType> : RxTableViewNo
// UITableViewDataSource
public override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
override func _numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sectionModels.count
}
public override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
override func _tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sectionModels[section].items.count
}
public override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
override func _tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
precondition(indexPath.item < sectionModels[indexPath.section].items.count)
let item = indexPath.item
@ -88,11 +133,11 @@ public class RxTableViewSectionedDataSource<S: SectionModelType> : RxTableViewNo
return cellFactory(tableView, indexPath, section.model, section.items[item])
}
public override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
override func _tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return titleForHeaderInSection?(section: section)
}
public override func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
override func _tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return titleForFooterInSection?(section: section)
}

View File

@ -11,7 +11,8 @@ import UIKit
import RxSwift
import RxCocoa
class RxTableViewSectionedReloadDataSource<S: SectionModelType> : RxTableViewSectionedDataSource<S>, RxTableViewReactiveDataSourceType {
class RxTableViewSectionedReloadDataSource<S: SectionModelType> : RxTableViewSectionedDataSource<S>
, RxTableViewDataSourceType {
typealias Element = [S]
func tableView(tableView: UITableView, observedEvent: Event<Element>) {

View File

@ -62,12 +62,12 @@
C8A56BCB1AD744E600B4673B /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8A56BCA1AD744E600B4673B /* RxSwift.framework */; };
C8A56BCC1AD744E600B4673B /* RxSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C8A56BCA1AD744E600B4673B /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
C8A57F741B40AF7C00D5570A /* Random.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C8A57F721B40AF7C00D5570A /* Random.xcdatamodeld */; };
C8C46DA81B47F7110020D71E /* CollectionViewImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C46DA31B47F7110020D71E /* CollectionViewImageCell.swift */; };
C8C46DA91B47F7110020D71E /* WikipediaImageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8C46DA41B47F7110020D71E /* WikipediaImageCell.xib */; };
C8C46DAA1B47F7110020D71E /* WikipediaSearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C46DA51B47F7110020D71E /* WikipediaSearchCell.swift */; };
C8C46DAB1B47F7110020D71E /* WikipediaSearchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8C46DA61B47F7110020D71E /* WikipediaSearchCell.xib */; };
C8C46DAC1B47F7110020D71E /* WikipediaSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C46DA71B47F7110020D71E /* WikipediaSearchViewController.swift */; };
C8DF92CD1B0B2F84009BCF9A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DF92C81B0B2F84009BCF9A /* AppDelegate.swift */; };
C8DF92D81B0B3174009BCF9A /* CollectionViewImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DF92D31B0B3174009BCF9A /* CollectionViewImageCell.swift */; };
C8DF92D91B0B3174009BCF9A /* WikipediaImageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8DF92D41B0B3174009BCF9A /* WikipediaImageCell.xib */; };
C8DF92DA1B0B3174009BCF9A /* WikipediaSearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DF92D51B0B3174009BCF9A /* WikipediaSearchCell.swift */; };
C8DF92DB1B0B3174009BCF9A /* WikipediaSearchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8DF92D61B0B3174009BCF9A /* WikipediaSearchCell.xib */; };
C8DF92DC1B0B3174009BCF9A /* WikipediaSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DF92D71B0B3174009BCF9A /* WikipediaSearchViewController.swift */; };
C8DF92DF1B0B328B009BCF9A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DF92DE1B0B328B009BCF9A /* AppDelegate.swift */; };
C8DF92E31B0B32DA009BCF9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8DF92E01B0B32DA009BCF9A /* LaunchScreen.xib */; };
C8DF92E41B0B32DA009BCF9A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C8DF92E11B0B32DA009BCF9A /* Main.storyboard */; };
@ -147,12 +147,12 @@
C8A2A2CA1B404A1200F11F09 /* Randomizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Randomizer.swift; sourceTree = "<group>"; };
C8A56BCA1AD744E600B4673B /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C8A57F731B40AF7C00D5570A /* Random.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Random.xcdatamodel; sourceTree = "<group>"; };
C8C46DA31B47F7110020D71E /* CollectionViewImageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewImageCell.swift; sourceTree = "<group>"; };
C8C46DA41B47F7110020D71E /* WikipediaImageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WikipediaImageCell.xib; sourceTree = "<group>"; };
C8C46DA51B47F7110020D71E /* WikipediaSearchCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WikipediaSearchCell.swift; sourceTree = "<group>"; };
C8C46DA61B47F7110020D71E /* WikipediaSearchCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WikipediaSearchCell.xib; sourceTree = "<group>"; };
C8C46DA71B47F7110020D71E /* WikipediaSearchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WikipediaSearchViewController.swift; sourceTree = "<group>"; };
C8DF92C81B0B2F84009BCF9A /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C8DF92D31B0B3174009BCF9A /* CollectionViewImageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewImageCell.swift; sourceTree = "<group>"; };
C8DF92D41B0B3174009BCF9A /* WikipediaImageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WikipediaImageCell.xib; sourceTree = "<group>"; };
C8DF92D51B0B3174009BCF9A /* WikipediaSearchCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WikipediaSearchCell.swift; sourceTree = "<group>"; };
C8DF92D61B0B3174009BCF9A /* WikipediaSearchCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WikipediaSearchCell.xib; sourceTree = "<group>"; };
C8DF92D71B0B3174009BCF9A /* WikipediaSearchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WikipediaSearchViewController.swift; sourceTree = "<group>"; };
C8DF92DE1B0B328B009BCF9A /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C8DF92E01B0B32DA009BCF9A /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = "<group>"; };
C8DF92E11B0B32DA009BCF9A /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
@ -329,8 +329,11 @@
C86E2F341AE5A0CA00C31024 /* Views */ = {
isa = PBXGroup;
children = (
C8DF92DD1B0B317C009BCF9A /* OSX */,
C8DF92D21B0B3174009BCF9A /* iOS */,
C8C46DA31B47F7110020D71E /* CollectionViewImageCell.swift */,
C8C46DA41B47F7110020D71E /* WikipediaImageCell.xib */,
C8C46DA51B47F7110020D71E /* WikipediaSearchCell.swift */,
C8C46DA61B47F7110020D71E /* WikipediaSearchCell.xib */,
C8C46DA71B47F7110020D71E /* WikipediaSearchViewController.swift */,
);
path = Views;
sourceTree = "<group>";
@ -411,25 +414,6 @@
path = OSX;
sourceTree = "<group>";
};
C8DF92D21B0B3174009BCF9A /* iOS */ = {
isa = PBXGroup;
children = (
C8DF92D31B0B3174009BCF9A /* CollectionViewImageCell.swift */,
C8DF92D41B0B3174009BCF9A /* WikipediaImageCell.xib */,
C8DF92D51B0B3174009BCF9A /* WikipediaSearchCell.swift */,
C8DF92D61B0B3174009BCF9A /* WikipediaSearchCell.xib */,
C8DF92D71B0B3174009BCF9A /* WikipediaSearchViewController.swift */,
);
path = iOS;
sourceTree = "<group>";
};
C8DF92DD1B0B317C009BCF9A /* OSX */ = {
isa = PBXGroup;
children = (
);
path = OSX;
sourceTree = "<group>";
};
C8DF92F41B0B4392009BCF9A /* 01 Introduction */ = {
isa = PBXGroup;
children = (
@ -517,11 +501,11 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C8C46DAB1B47F7110020D71E /* WikipediaSearchCell.xib in Resources */,
C8DF92E31B0B32DA009BCF9A /* LaunchScreen.xib in Resources */,
C8C46DA91B47F7110020D71E /* WikipediaImageCell.xib in Resources */,
C8DF92EA1B0B38C0009BCF9A /* Images.xcassets in Resources */,
C8DF92E41B0B32DA009BCF9A /* Main.storyboard in Resources */,
C8DF92DB1B0B3174009BCF9A /* WikipediaSearchCell.xib in Resources */,
C8DF92D91B0B3174009BCF9A /* WikipediaImageCell.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -551,10 +535,10 @@
C8DF92E51B0B32DA009BCF9A /* RootViewController.swift in Sources */,
C859B9A81B45C83700D012D7 /* RxCollectionViewSectionedDataSource.swift in Sources */,
C88C788F1B3F14FD0061C5AB /* Changeset.swift in Sources */,
C8C46DA81B47F7110020D71E /* CollectionViewImageCell.swift in Sources */,
C8C46DAC1B47F7110020D71E /* WikipediaSearchViewController.swift in Sources */,
0706E19D1B176EE200BA2D3A /* String+extensions.swift in Sources */,
C8DF92DC1B0B3174009BCF9A /* WikipediaSearchViewController.swift in Sources */,
C88C78731B3EB0A00061C5AB /* SectionModel.swift in Sources */,
C8DF92D81B0B3174009BCF9A /* CollectionViewImageCell.swift in Sources */,
C86E2F3F1AE5A0CA00C31024 /* SearchViewModel.swift in Sources */,
0706E1961B14AF5100BA2D3A /* DetailViewController.swift in Sources */,
C88C78991B4012A90061C5AB /* SectionModelType.swift in Sources */,
@ -567,6 +551,7 @@
C83367231AD029AE00C668A7 /* Example.swift in Sources */,
C890A65D1AEC084100AFF7E6 /* ViewController.swift in Sources */,
C88C78951B3F20DB0061C5AB /* Differentiator.swift in Sources */,
C8C46DAA1B47F7110020D71E /* WikipediaSearchCell.swift in Sources */,
C890A6581AEBD26B00AFF7E6 /* GitHubSignupViewController.swift in Sources */,
C8A57F741B40AF7C00D5570A /* Random.xcdatamodeld in Sources */,
C88C786F1B3EB0A00061C5AB /* RxTableViewSectionedReloadDataSource.swift in Sources */,
@ -575,7 +560,6 @@
07E300071B14995F00F00100 /* TableViewController.swift in Sources */,
C859B9A41B45C5D900D012D7 /* PartialUpdatesViewController.swift in Sources */,
07E3C2331B03605B0010338D /* Dependencies.swift in Sources */,
C8DF92DA1B0B3174009BCF9A /* WikipediaSearchCell.swift in Sources */,
C86E2F451AE5A0CA00C31024 /* WikipediaAPI.swift in Sources */,
C8DF92CD1B0B2F84009BCF9A /* AppDelegate.swift in Sources */,
C88C786E1B3EB0A00061C5AB /* RxTableViewSectionedDataSource.swift in Sources */,

View File

@ -54,14 +54,14 @@ class GitHubAPI {
}
>- observeSingleOn(self.dataScheduler)
>- catch { result in
return returnElement(false)
return just(false)
}
}
func signup(username: String, password: String) -> Observable<SignupState> {
// this is also just a mock
let signupResult = SignupState.SignedUp(signedUp: arc4random() % 5 == 0 ? false : true)
return concat([returnElement(signupResult), never()])
return concat([just(signupResult), never()])
>- throttle(5, MainScheduler.sharedInstance)
>- startWith(SignupState.SigningUp)
}

View File

@ -30,12 +30,12 @@ class ValidationService {
func validateUsername(username: String) -> Observable<ValidationResult> {
if count(username) == 0 {
return returnElement((false, nil))
return just((false, nil))
}
// this obviously won't be
if username.rangeOfCharacterFromSet(NSCharacterSet.alphanumericCharacterSet().invertedSet) != nil {
return returnElement((false, "Username can only contain numbers or digits"))
return just((false, "Username can only contain numbers or digits"))
}
let loadingValue = (valid: nil as Bool?, message: "Checking availabilty ..." as String?)

View File

@ -58,13 +58,21 @@ class PartialUpdatesViewController : ViewController {
}
func skinCollectionViewDataSource(dataSource: RxCollectionViewSectionedDataSource<NumberSection>) {
dataSource.cellFactory = { (cv, ip, s, i) in
dataSource.cellFactory = { [unowned dataSource] (cv, ip, i) in
let cell = cv.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: ip) as! NumberCell
cell.value!.text = "\(i)"
return cell
}
dataSource.supplementaryViewFactory = { [unowned dataSource] (cv, kind, ip) in
let section = cv.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "Section", forIndexPath: ip) as! NumberSectionView
section.value!.text = "\(dataSource.sectionAtIndex(ip.section).model)"
return section
}
}
override func viewDidLoad() {
@ -73,6 +81,7 @@ class PartialUpdatesViewController : ViewController {
self.sections.next(generator.sections)
let tvAnimatedDataSource = RxTableViewSectionedAnimatedDataSource<NumberSection>()
//let cvAnimatedDataSource = RxCollectionViewSectionedReloadDataSource<NumberSection>()
let cvAnimatedDataSource = RxCollectionViewSectionedAnimatedDataSource<NumberSection>()
let reloadDataSource = RxTableViewSectionedReloadDataSource<NumberSection>()
@ -102,6 +111,7 @@ class PartialUpdatesViewController : ViewController {
updates
>- partialUpdatesCollectionViewOutlet.rx_subscribeWithReactiveDataSource(cvAnimatedDataSource)
>- disposeBag.addDisposable
}
@IBAction func randomize() {

View File

@ -33,7 +33,7 @@ public class WikipediaSearchCell: UITableViewCell {
let disposeBag = DisposeBag()
self.titleOutlet.rx_subscribeTextTo(viewModel?.title ?? returnElement("")) >- disposeBag.addDisposable
self.titleOutlet.rx_subscribeTextTo(viewModel?.title ?? just("")) >- disposeBag.addDisposable
self.URLOutlet.text = viewModel.searchResult.URL.absoluteString ?? ""
viewModel.imageURLs

View File

@ -62,14 +62,14 @@ class DefaultImageService: ImageService {
// best case scenario, it's already decoded an in memory
if let image = maybeImage {
decodedImage = returnElement(image)
decodedImage = just(image)
}
else {
let cachedData = self.imageDataCache.objectForKey(URL) as? NSData
// does image data cache contain anything
if let cachedData = cachedData {
decodedImage = returnElement(cachedData) >- self.decodeImage
decodedImage = just(cachedData) >- self.decodeImage
}
else {
// fetch from network

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="E5v-jn-n2n">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="E5v-jn-n2n">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
@ -246,11 +246,11 @@
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</tableView>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="hob-nw-Jrs">
<rect key="frame" x="212.5" y="64" width="91.5" height="504"/>
<rect key="frame" x="212.5" y="64" width="107.5" height="504"/>
<color key="backgroundColor" cocoaTouchSystemColor="tableCellGroupedBackgroundColor"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="m51-be-PcL">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="50" height="50"/>
<size key="itemSize" width="55" height="35"/>
<size key="headerReferenceSize" width="50" height="25"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
@ -259,10 +259,10 @@
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<rect key="frame" x="0.0" y="0.0" width="55" height="35"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vIm-V4-xJI">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vIm-V4-xJI">
<rect key="frame" x="4" y="14.5" width="42" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
@ -280,17 +280,19 @@
</connections>
</collectionViewCell>
</cells>
<collectionReusableView key="sectionHeaderView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="myv-cg-TS9" customClass="NumberSectionView" customModule="RxExample" customModuleProvider="target">
<collectionReusableView key="sectionHeaderView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="Section" id="myv-cg-TS9" customClass="NumberSectionView" customModule="RxExample" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="91.5" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dob-Ct-qBk">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dob-Ct-qBk">
<rect key="frame" x="24" y="14.5" width="42" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" red="0.98431372549999996" green="0.98431372549999996" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="centerY" secondItem="Dob-Ct-qBk" secondAttribute="centerY" id="3Hw-f1-oiE"/>
<constraint firstAttribute="centerX" secondItem="Dob-Ct-qBk" secondAttribute="centerX" id="QpP-Og-cie"/>
@ -314,7 +316,7 @@
<constraint firstItem="hUq-CB-rKx" firstAttribute="top" secondItem="Q1a-BU-VHX" secondAttribute="topMargin" id="egs-zL-uq3"/>
<constraint firstItem="hob-nw-Jrs" firstAttribute="top" secondItem="rR0-FR-HFT" secondAttribute="bottom" id="mhG-uk-0Mw"/>
<constraint firstItem="6z9-hh-u3N" firstAttribute="leading" secondItem="hUq-CB-rKx" secondAttribute="trailing" id="mvK-ZN-p0d"/>
<constraint firstAttribute="trailingMargin" secondItem="hob-nw-Jrs" secondAttribute="trailing" id="zCf-tB-0ls"/>
<constraint firstAttribute="trailing" secondItem="hob-nw-Jrs" secondAttribute="trailing" id="zCf-tB-0ls"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="atr-kQ-uig">
@ -332,7 +334,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iOF-ih-lLu" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-787" y="815"/>
<point key="canvasLocation" x="-789" y="815"/>
</scene>
<!--Rx Examples-->
<scene sceneID="TnT-xx-y5Q">