rxswiftcommunity / rxdatasources Goto Github PK
View Code? Open in Web Editor NEWUITableView and UICollectionView Data Sources for RxSwift (sections, animated updates, editing ...)
License: MIT License
UITableView and UICollectionView Data Sources for RxSwift (sections, animated updates, editing ...)
License: MIT License
Hi
Consider the following scenario: I have a table view that contains 2 sections. Section 1 contains multiple products (Product
model) and Section 2 contains multiple payment methods (PaymentMethod
model). How can I create an Rx-based DataSource that contains both models so that I can display their appropriate cells/data in the tableview?
Thanks for the great library. It's awesome!
—Kishyr
Hi,
What is the ETA for a Swift 3 version of RxDataSources?
Cheers.
0.9 appears to introduce two CocoaPods specific custom build steps. This causes the build to fail if you didn't use CocoaPods to obtain it. Not everyone uses CocoaPods so what is the purpose and can it be made conditional so not to affect those not installing in their project via CocoaPods?
Would be nice to define collectionView(_:layout:referenceSizeForHeaderInSection:)
in the same way we define supplementaryViewFactory
By default collectionView(_:layout:referenceSizeForHeaderInSection:)
returns (0,0) as described here unless the user either implements the delegate or defines headerReferenceSize
property of the UICollectionViewFlowLayout link. When the size in the appropriate scrolling dimension is 0, no header is added.
I was trying to use a custom header registered using the method registerNib(_:forSupplementaryViewOfKind:withReuseIdentifier:)
and I couldn't figured out why it was not working. Then, I realised it was the size but to define I had to implement the delegate which is annoying because I use RxDataSources
for the view and the UICollectionViewDelegateFlowLayout
for the size of the same view.
In the project Example2
everything work because the header is defined in the Storyboard inside the collection view, in that case the UICollectionViewDelegateFlowLayout
inherits the headerReferenceSize
property, but defining custom header is a common use case
The UITableView dataSource implementation of the method tableView(_:canEditRowAtIndexPath:)
is returning true by default.
This can cause unexpected behaviour when using RxDataSource, an example is the Customization using table view delegate
in the Example app that shows the delete button when sliding the cell from the right to the left.
According with the documentation the default value should be:
Return Value
true if the row indicated by indexPath is editable; otherwise, false.
I'm not sure if this is an issue or an inquiry.
AnimatableSectionModel seems to not be used anywhere and I'm not sure if it's something that I should use in my project.
If my section model extends AnimatableSectionModelType do I need to still declare something like this?
let sectionModel = AnimatableSectionModel<Section, Item>()
I implemented moveItem for my CollectionViewSectionedDataSource but it is never called.
I am seeing a strong retain when using "datasource.configureCell = ...."
Unless i call dataSource.configureCell = nil in the viewController the class that owns the dataSource will never be disposed.
Hi all, I am using RxDataSources with RxRealm, my question is
how to bind realm to dataSource with multiple section model?
let dataSource = RxTableViewSectionedReloadDataSource<MySectionModel>()
let realm = try! Realm()
let configures = realm.objects(Configure).asObservable()
configures.bindTo ...???
thx!
I have a list of items and a view controller to edit their titles. When I modify the information, the event is passed to RxTableViewSectionedAnimatedDataSource but the differencesForSectionedView doesn't return any differences, so no cells get updated.
As I look a little deeper, I can't find any functionality related to checking item properties for differences. Is this correct?
Hi there, I was looking at the Editing Example
in the repo and every time I try to move a row from a section to another section the app crashes whit this stack:
2016-05-12 12:46:36.100 Example[23517:225683] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.60.7/UITableView.m:1540
2016-05-12 12:46:40.265 Example[23517:225683] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to move index path (<NSIndexPath: 0xc000000000000216> {length = 2, path = 2 - 0}) that does not exist - there are only 0 rows in section 2 before the update'
*** First throw call stack:
(
0 CoreFoundation 0x000000010ec7bd85 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000110a1fdeb objc_exception_throw + 48
2 CoreFoundation 0x000000010ec7bbea +[NSException raise:format:arguments:] + 106
3 Foundation 0x000000010f0ccd5a -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198
4 UIKit 0x000000010f5d1fbb -[UITableView _endCellAnimationsWithContext:] + 9755
5 RxDataSources 0x000000010eac4e5a _TFE13RxDataSourcesCSo11UITableView19performBatchUpdatesuRxS_16SectionModelTyperfTGVS_9Changesetx_22animationConfigurationVS_22AnimationConfiguration_T_ + 890
6 RxDataSources 0x000000010ea95529 _TFFFC13RxDataSources38RxTableViewSectionedAnimatedDataSource9tableViewFTCSo11UITableView13observedEventGO7RxSwift5EventGSax___T_U_FTGS0_Q__GSaQ___T_U_FT_T_ + 2313
7 RxDataSources 0x000000010ea95717 _TTRXFo__dT__XFdCb__dT__ + 39
8 libdispatch.dylib 0x00000001124e6d9d _dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x00000001125073eb _dispatch_client_callout + 8
10 libdispatch.dylib 0x00000001124ef1ef _dispatch_main_queue_callback_4CF + 1738
11 CoreFoundation 0x000000010ebd50f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
12 CoreFoundation 0x000000010eb96b99 __CFRunLoopRun + 2073
13 CoreFoundation 0x000000010eb960f8 CFRunLoopRunSpecific + 488
14 GraphicsServices 0x00000001162d5ad2 GSEventRunModal + 161
15 UIKit 0x000000010f4a3f09 UIApplicationMain + 171
16 Example 0x000000010e535ad2 main + 114
17 libdyld.dylib 0x000000011253b92d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Hi, I am experiencing the need to:
A tableview needs to display the content section of an article and a list of comments for the article.
So, the content and the comments of the cell is different types, so they come from different data model, this situation should be how to use RxDatasources to achieve?
Hello,
I've got a small amount of crashes on Fabric that seem to be triggered sometimes when calling the performBatchUpdates method.
The error displayed is the following:
UITableView internal bug: unable to generate a new section map with old section count: 2 and new section count: 0
I am initialising the View Controller with 2 sections (0 cells until the data is loaded from the server) and never remove them. I only replace them by an updated version in my handler method, which returns a new set of 2 sections.
Any ideas are much appreciated! Thanks.
I was initializing one of my static AnimatableSectionModelType section as follows:
let someStaticSection: AnimatableMultipleSectionModel =
.someStaticSection(
title: "foo",
items: (1...3).map{ _ in .staticSectionItem(image: UIImage(named: "myImage")!, title: "sample title") }
)
and in another section that represents my observable data I was doing:
let observableSection: AnimatableMultipleSectionModel =
.myDataSection(
title: "my data",
items: myObservableData.map{ .myDataSectionItem( \*some initialization here*\ ) }
)
.someStaticSection
was throwing DifferentiatorError.duplicateItem
exception and I had animations broken in .myDataSection
. I didn't notice the exception for quite a while and had no idea why the animations were not working. As soon as I replaced my .someStaticSection
with differentiated items the animations in .myDataSection
started working.
I think it's an unintended behavior because unrelated sections should not affect animations of other sections within tableView. If duplicate items within a section is truly an exception behavior of the dataSource, shouldn't the program execution be aborted if the client doesn't catch the exception? And even if he does handle errors, why should business logic of sections initialization alter the way animations work?
Hi guys
I'm trying to model my sections and items as enums as implemented in MultipleSectionModelViewController.swift
in the Example to be able to use the MultipleSectionModel
with RxCollectionViewSectionedAnimatedDataSource<MultipleSectionModel>
.
I know that I have to make the MultipleSectionModel
conforms to AnimatableSectionModelType
but I'm not having good time with the associatedtype
defined in AnimatableSectionModelType
.
In the Example app the typealias
is defined like this
extension MultipleSectionModel: SectionModelType {
typealias Item = Any
.....
}
My question is how I can implement the same but doing something like:
extension MultipleSectionModel: AnimatableSectionModelType {
typealias Item = Any // Here Any doesn't work because Any is not conform to SectionModelType, IdentifiableType
}
Note: I want still be able to use multiple type as the example uses ImageSectionItem, ToggleableSectionItem, StepperSectionItem
Using the method func model(_ indexPath: IndexPath) throws -> Any
of CollectionViewSectionedDataSource
I received few crash reports because of Index out of range
.
The description of the method says:
Returns model at index path. In case data source doesn’t contain any sections when this method is being called, RxCocoaError.ItemsNotYetBound(object: self) is thrown.
I was wondering if the library can help also with the out of range error.
RxDataSources is a very nice library.
Thank you.
I'd like to implement this function also in ASCollectionNode of AsyncDisplayKit.
However, since RxDataSources depends on the DelegateProxy of RxCocoa,
Since some methods are Internal, it is difficult to implement "ASCollectionNode + Rx".
Is there any good idea?
AsyncDisplayKit
ASCollectionNode
If I can realize it will be published in the following repository
https://github.com/muukii/RxAsyncDataSources
So this is how my Podfile
looks (the part that matters for this):
pod 'RxSwift', '~> 2.0.0'
pod 'RxCocoa', '~> 2.0.0'
pod 'RxDataSources', '~> 0.1'
And this is my Podfile.lock
- RxCocoa (2.0.0):
- RxSwift (~> 2.0)
- RxDataSources (0.3):
- RxCocoa (~> 2.0)
- RxSwift (~> 2.0)
- RxSwift (2.0.0)
- RxViewModel (3.0.0):
- RxCocoa (~> 2.0.0)
- RxSwift (~> 2.0.0)
As you can see i'm using 2.0.0
for RxSwift
and RxCocoa
and 0.3
for RxDataSources
but I can't compile my project.
I'm targeting iOS 8.1
and can't compile because public class CollectionViewSectionedDataSource<S: SectionModelType>
and public class RxTableViewSectionedDataSource<S: SectionModelType>
can't find SectionedViewDataSourceType
After checking RxCocoa
podspec
and RxDataSources
RxCocoa
2.1.0
is the one that includes SectionedViewDataSourceType
and RxDataSources
podspec
depends on 2.0.0
making the project impossible to compile at the moment
I have the following code:
viewModel.tableViewSections.bindTo(tableView.rx_itemsWithDataSource
....
viewModel.tableViewDataSource.configureCell = {
...
This is working in previous release but now throwing assert, what is the proper way of doing this?
Since Swift 2.2 (Xcode 7.3+), use of curried functions is deprecated. It will be marked as an error in Swift 3.0. It means only single parameter list functions will be allowed.
The README still has lots of passages that refer to functions likerx_items(dataSource:protocol<RxTableViewDataSourceType, UITableViewDataSource>)
, which is now rx_itemsWithDataSource(dataSource:protocol<RxTableViewDataSourceType, UITableViewDataSource>)
. Several of the code snippets also reference .rx.items()
, which is also no longer correct.
The README needs to be updated - each code snippet should be copy-pastable and should work without further modifications.
I am trying to configure a custom header for my table cell using a prototype UITableViewCell with a different reuse identifier. I only see an example of using default headers... Is this possible?
While setting new items to animatable data source, the app will crash due to:
2016-06-28 15:39:19.024 myproapp[28226:12219321] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
I have animatable data source with 2 sections: 1 section having one item, another section having more than 1 item (about 10).
Change the source to 2 sections: 1 without any items (from 1), and second with the same items as before.
App will crash (well, depends if the steps above all enough for it).
So I was able to check the code out for a few minutes, and I found a quick fix (dunno if it's anyhow good, just pasting it here, maybe it will help with normal fix).
Basically in RxTableViewSectionedAnimatedDataSource.swift I changed the lines:
do {
let differences = try differencesForSectionedView(oldSections, finalSections: newSections)
for difference in differences {
dataSource.setSections(difference.finalSections)
tableView.performBatchUpdates(difference, animationConfiguration: self.animationConfiguration)
}
}
to:
do {
let differences = try differencesForSectionedView(oldSections, finalSections: newSections)
dataSource.setSections(newSections)
for difference in differences {
tableView.performBatchUpdates(difference, animationConfiguration: self.animationConfiguration)
}
}
It seems like it returns wrong finalSections
from differences
in my use-case. But I figured that the variable newSections
should have the proper final sections anyways. I didn't have time to dig more into the code so I filled an issue here.
Cheers! 🐼
Is there a way to customize the header view for RxTableViewDatasource?
I folowed the instructions on the example and this is the error i got on:
tableView.rx_itemsWithDataSource(dataSource)
error:
Cannot invoke 'rx_itemsWithDataSource' with an argument list of type '(RxTableViewSectionedAnimatedDataSource)'
I would like to customize insert / delete animations when using a RxTableViewSectionedAnimatedDataSource
. But it looks like AnimationConfiguration
properties and initializers are marked internal
, even though the struct itself is public
.
Consider marking all fields and initializers public
in this struct.
Cheers.
Maybe I'm missing it but shouldn't we have these two methods?
A crash occurs when a long press is performed on a cell, when using a RxCollectionViewSectionedReloadDataSource
.
Apparently, the data source proxy does not implement the collectionView(_:,canMoveItemAtIndexPath:)
data source function introduced in iOS 9 to allow cell reordering.
is:issue is:open .../Pods/RxDataSources/Sources/DataSources/AnimatableSectionModel.swift:96:61: 'HashableSectionModel' is deprecated: Please use AnimatableSectionModel or your own model implementing AnimatableSectionModelType
When I am trying to submit an IPA to Apple that includes the framework (build with Carthage) I get:
ERROR ITMS-90060: "This bundle is invalid.
The value for key CFBundleShortVersionString '1.0.0.beta.1' in the Info.plist file must be a period-separated list of at most three non-negative integers."
Hi, how to achieve UITableViewRowAction with rxdatasources?
Hi guys, thanks for the great work. To make this easier to understand and to widen the audience simpler examples would be awesome.
Even for someone who is used to RX extensions from the Microsoft world and Angular2 it's still very hard to get this implemented, in particular when under time pressure. I am sure that a lot of less experienced developers just give up which is a pity.
Perhaps start with the most basic UITableViewController and UICollectionViewController implementation and work your way upwards.
Randomly I'm facing crashes when using RxCollectionViewSectionedAnimatedDataSource, or at least when using the non animated flavour is seems to be stable. When a crash occurs the stack trace, reports me a
Fatal Exception: NSInternalInconsistencyException
with a message:
Invalid update: invalid number of sections. The number of sections contained in the collection view after the update (3) must be equal to the number of sections contained in the collection view before the update (3), plus or minus the number of sections inserted or deleted (1 inserted, 0 deleted).
It seems to happen after UI+SectionedViewType.swift line 98 and will crash somewhere in UICollectionView _performBatchUpdates:completion:invalidationContext:
This does not happen when using a RxCollectionViewSectionedReloadDataSource, so my question is more if this is a known issue and if anybody facing the same kind of issue resolved it, any help is appreciated. I'm using RxDatasource version 0.6.2.
Hi,
Have you considered using a more generic CollectionType
as type of the items
property of SectionModelType
(instead of [Item]
). This might allow the use of lazy collections for table views / collection views with a very large dataset.
Would that be possible, or am I missing something ?
Maybe it would be useless for animated sectioned data sources though, due to their need to compare sections and rows to each others.
Tell me what you think about it.
Btw, thanks for all the wonderful Rx extensions :-)
Cheers,
Damien
I'm not sure what the preferred solution would be. Here are a couple ideas that come to mind:
Since Swift 2.2 (Xcode 7.3+), use of typealias
is deprecated in protocols. It has been replaced by the keyword associatedtype
. It will be marked as an error in Swift 3.0.
First of all, thanks for the great work on RxSwift! I'm really enjoying working with it. :D
That being said; I'm currently experiencing a potential leak when using tableView.rx_itemsAnimatedWithDataSource
.
I have a UIViewController
polling the server and binding the result to a UITableView
:
https://github.com/wouterw/leak/blob/master/Leak/ViewController.swift
This VC is inside a UITabBarController
and should stop polling when not visible. In order to achieve this behaviour I'm subscribing inside viewWillAppear
and disposing inside the viewWillDisappear
hook.
This approach seems to work for simpler Observables
(e.g. Driver<Int>.interval(1)
), but not when using in combination with tableView.rx_itemsAnimatedWithDataSource
.
I've setup a minimal app demonstrating the problem here: https://github.com/wouterw/leak.
I loved this rx datasources implementation. It makes very simple and reusable to implemente uitableview based view controllers. Do you have any plans to implement similar rx abstractions for uitableview/uicollection view delegates ?
Given the example project I'm not sure on how to modify or append one individual row without recreating a whole section. Could you provide a simple example? Thanks
According to semantic versioning 0.x updates must not be breaking: http://semver.org/#spec-item-8
Hi, I'm doing a app targets iOS 8.3, after I add RxDataSource with carthage and import it, it's said the minimum deploy target version is 9.0.
I don't know the reason RxDataSource was set like this. but in this way, you may lost huge mount of uses.
Is that possible to make the minimum deploy target version lower like 8.0 or 7.0?
and, I really want to use RxDataSource by carthage, any work around of this problem?
thanks.
I need to reset dataSet variable in RxCollectionViewSectionedAnimatedDataSource to false so my collection view will perform a reload instead of partial update. Currently, it's default to internal. Alternatively, is there a work around to reload the collection view using AnimatableSectionModelType?
How can I add an additional cell to the end of the collectionView? with native implementation, I would do something as follow:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count + 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.row < items.count {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RegularCell", for: indexPath) as! RegularCell
// configure regular cell
return cell
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SpecialCell", for: indexPath) as! SpecialCell
// this cell has different layout with no SectionModel item, configureCell does not get called
return cell
}
Can I achieve something similar with RxDataSource?
I install RxDataSource with cocoapod, after pod install successfully, my app crash and show the error message when I run it like follows:
dyld: Library not loaded: @rpath/RxDataSources.framework/RxDataSources
Referenced from: /Users/feilang001/Library/Developer/CoreSimulator/Devices/F6C9FC56-F6A5-4F24-8180-E724D7F76EF1/data/Containers/Bundle/Application/ECEA79C2-336D-4560-B3E3-1304E4CA5358/ProcessControl.app/ProcessControl
Reason: image not found
I found solution on stackoverflow that add the dynamic framework to the Embedded binaries section in the General tab of the project. But anyone else who works in my team must do this again at first,is there some other better ways to solve this?
RxTableViewSectionedDataSource
, CollectionViewSectionedDataSource
and their properties and classes should be open
instead of public
to enable subclassing.
Since, Xcode 7.3, segmentation faults occur in TableViewSectionedDataSource.swift
and CollectionViewSectionedDataSource.swift
.
Concerning TableViewSectionedDataSource.swift
, it looks like the faults come from these 4 functions:
override func _tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
override func _tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool
override func _sectionIndexTitlesForTableView(tableView: UITableView) -> [String]?
override func _tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int
I think the compiler does not like super._tableView(...)
that much...
Concerning CollectionViewSectionedDataSource.swift
, it looks like the faults come from these 2 functions:
override func _collectionView(collectionView: UICollectionView, canMoveItemAtIndexPath indexPath: NSIndexPath) -> Bool
override func _collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)
As for table view, the compiler does not seem to like super._collectionView(...)
.
import RxSwift
import RxCocoa
import RxDataSources
class ViewController: UIViewController, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Double>>()
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
dataSource.configureCell = { (ds, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(element) @ row \(indexPath.row)"
return cell
}
let items = Observable.just([
SectionModel(model: "First section", items: [ 1.0, 2.0, 3.0 ]),
SectionModel(model: "Second section", items: [ 1.0, 2.0, 3.0 ]),
SectionModel(model: "Third section", items: [ 1.0, 2.0, 3.0 ])
])
items
.bindTo(tableView.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag)
tableView.rx
.setDelegate(self)
.addDisposableTo(disposeBag)
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
print("\(tableView.numberOfSections) - \(section)")
let label = UILabel(frame: CGRect.zero)
label.text = dataSource.sectionAtIndex(section).model
return label
}
}
The outputs I get:
3 - 1
3 - 2
It looks as if the first section is being ignored. This is also reflected in the tableView as the first header is empty
Hello, first of all thanks for your fantastic work with RxSwift.
For someone like me who's learning RxSwift, I feel like RxDataSources could use a little more documentation in order to provide some sort of general understanding of how things work. I'm all for reading source code/trying examples, but sometimes it can be quite overwhelming without some sort of general understanding/mental framework...
In addition, DataSource binding is quite specific to RxSwift and its not possible to get more info from other Rx implementations.
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.