Comments (10)
Thanks for making this library.
While I agree that basing the size off of data rather than autolayout is preferrable and more performant, I think that not having an "intrinsicSizeSizeProvider" or similar greatly limits the usefulness of the whole library. With how autolayout heavy iOS code usually is, this is a must have feature for me.
Below is an example of a simple tableView like layout with dynamic cell height:
@IBOutlet weak var collectionView: CollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let provider = CollectionProvider(data: ["firstfdshafhjkdajkhfdhkjfdahjhkgjfdaghdfagkhjadfghkjfdaghkjdfghjkakghjadfkghjfadghkjfdahjkgashjgkfdhjgkdfsahjgkdfashjgkfadsghjkfadhjgkhjgkfahjkgaf", "second"], viewUpdater: { (label: UILabel, data: String, index: Int) in
label.numberOfLines = 0
label.text = data
label.backgroundColor = index == 0 ? .red : .green
})
provider.sizeProvider = { [unowned provider] (index,_, collectionSize) in
let v = provider.view(at: index)
return CGSize(
width: collectionSize.width,
height: v.systemLayoutSizeFitting(CGSize(width: collectionSize.width, height: UILayoutFittingCompressedSize.height)).height
)
}
collectionView.provider = provider
}
The problem with this approach is that you have to do the whole [unowned]
dance and have to split the initialization into multiple steps. Similar code is bound to be repeated in many apps that use CollectionKit, but there arent good ways to simplify it.
Making this a feature of CollectionKit would be quite simple, but requires API breaking changes (at the very least, making the CollectionProvider or the View a parameter of the SizeProvider function). I might make a PR if I find the time, but first I wonder how the author feels about this and if they have any suggestions for how the new API should look (or any strong arguments against adding this feature).
from collectionkit.
@pteasima
Using AutoLayout for each cell greatly impact the performance of collection view. Because collection view can have thousands of cells, CollectionView only initializes views that are on screen. You don't want to create thousands of views for getting the sizes when there are only a few that is displayed.
If we were to implement some way to use autolayout, we would be creating a dummy cell in the memory and use that to retrieve the size.
from collectionkit.
Thanks, I didnt realize that CollectionKit needs to calculate all sizes upfront. I can still imagine it might be possible to only calculate sizes lazily. I think UITable/CollectionView do this somehow. It would involve constantly updating the contentSize as the user scrolls and new cell sizes get calculated. Updating the contentSize could mess up scrolling etc. While I think its doable (and I believe apple does this), its a hard problem and not one that can be solved without vast changes to the whole library. So, as I said, I give up and consider this matter closed ;)
Also, I see the benefit of your "prototype cell" solution over mine, but as you said its still not nearly performant enough.
from collectionkit.
What is the view you get inside your sizeProvider
?
let view = provider1.view(at: index)
Could you check its class?
If it is a GenericSingleLineInputView
, could you check its title and subtitle's content?
Usually for sizeProvider, you'd better calculate size based on data instead of using view to do that.
from collectionkit.
Usually for sizeProvider, you'd better calculate size based on data instead of using view to do that.
Thanks for that info. I have planned to do this, but thought maybe there is another way to solve this issue. Thank you!
from collectionkit.
@bernhardwaidacher would you mind reopening the issue so that we can get a reaction? I dont wanna start a new issue since it follows the discussion here.
from collectionkit.
@lkzhao Thanks for the reply. I agree that autolayout is slow but I dont quite get the "thousands of views" point. My sample code above seems to work even for large numbers of elements.
Is there a situation where CollectionKit asks for a size but the view hasnt been created and thus cannot be used for calculating size? This would make by solution from above impossible. I still have some ideas how to handle this but it would likely require bigger changes (and I would likely give up:))
from collectionkit.
scratch that. I digged into the source and now I get your point. My confussion was that I didnt realize that provider.view(at:) actually constructs the view, I thought it will have been constructed and this is only a getter. Thanks for your time.
from collectionkit.
@bernhardwaidacher with this new information, I discourage using my sample code from above. It really does create all views eagerly and the performance will be terrible.
from collectionkit.
@pteasima
Try this maybe.
class ViewController: UIViewController {
let collectionView = CollectionView()
override func viewDidLoad() {
super.viewDidLoad()
let dummyCell = YourView()
let viewUpdater = { (view: YourView, data: Int, index: Int) in
view.backgroundColor = .red
//...
}
collectionView.provider = CollectionProvider(
data: [1],
viewUpdater: viewUpdater,
sizeProvider: { (index, data, maxSize) -> CGSize in
viewUpdater(dummyCell, data, index) // first update the cell with current index's data
return dummyCell.systemLayoutSizeFitting(maxSize)
})
}
}
keep in mind that performance of this won't be great for a lot of cells.
There is also the ViewCollectionProvider
class which is a special CollectionProvider
that allows you to use existing views if you have them constructed already.
from collectionkit.
Related Issues (20)
- Is there an oc version?
- Some one make swipe to delete?
- how scroll to item? HOT 1
- To centered items into collection view
- How to create Context Menu for cells?
- How to animate a Collection View from another Collection View? HOT 1
- [Bug] Changing mode cause duplications
- How to keep scroll position ? HOT 2
- Control a section view of ComposedHeaderProvider?
- Support RTL Directions
- Using CollectionView Cell with IBOutlets built using XIB , crashes with nil HOT 1
- build faild with error
- multi-view cast view type error
- How to add background view to BasicProvider?
- Question?
- How to achieve vertical waterfall flow effect HOT 1
- horizontal scrolling? HOT 1
- SPM Support?
- About ReloadData
- How to use AutoLayoutSizeSource
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from collectionkit.