dentelezhkin / dtcollectionviewmanager Goto Github PK
View Code? Open in Web Editor NEWProtocol-oriented UICollectionView management, powered by generics and associated types.
License: MIT License
Protocol-oriented UICollectionView management, powered by generics and associated types.
License: MIT License
I'm wondering if there is a way to use different model-types for a collection-view cell.
I have two types: Book and Movie. Each type has a title, and an associated image.
What I'd like to do is use the same UICollectionViewCell (let's call it GenericCell
) and register it so that a different type can be used, besides the one that is defined in the cell's ModelType
.
Barring that, maybe a runtime transform?... so I could see "Oh the model is a Book
, so transform it to a ImageTitle
object". Then the ModelType
and update
routine would use ImageTitle
even though the object from the data-source was actually a Book
or Movie
or whatever.
Random crashes may happen because this issue:
https://openradar.appspot.com/28167779
I use DTCollectionViewManager with Realm, it threw this error:
Fatal Exception: RLMException
Index 6 is out of bounds (must be less than 0)
Hello, I really like your extension, it's awesome!
But, do you think about separate controller and UIViewController classes. I think It will be better to encapsulate UICollectionView logic inside a NSObject-controller, and add it's as a property to your UIViewController. Because for example I use separate logic for views and controllers, using MVVM pattern, and this realisation sometimes is painfully for my architecture.
What do you think about this?
Hello! Why is collection view in DTCollectionViewManageable optional? It will be better if it is nonoptional value like in DTTableViewManageable
public protocol DTTableViewManageable : class
{
/// Table view, that will be managed by DTTableViewManager
var tableView : UITableView! { get }
}
public protocol DTCollectionViewManageable : class
{
/// Collection view, that will be managed by DTCollectionViewManager
var collectionView : UICollectionView? { get }
}
After I updated to the swift 3 version (5.0.0-beta.2), this error shows up:
Generic parameter 'T' could not be inferred.
What I'm trying to do with my collection view is that I want to show a bunch of colors for the user to choose from. Here is the cell class:
class ColorCell: UICollectionViewCell, ModelTransfer {
typealias ModelType = UIColor
func update(with model: UIColor) {
layer.cornerRadius = self.w / 2
layer.borderWidth = 1.5
self.backgroundColor = model
}
}
Then, I wrote a method with this signature:
func selectedColor(_ cell: ColorCell, color: UIColor, indexPath: IndexPath) {
}
So far so good. But the error appears on this line:
manager.didSelect(ColorCell.self, ColorSelectorController.selectedColor)
It says that T
cannot be inferred! But obviously T
is ColorCell
!
I have about 10 collections in my app that I expect to render... only one of them should be user-orderable.
What's the recommended way to turn off movable cells in DTCollectionViewManager for an entire UICollectionView?
Took me a bit to time to get the order of setup & that I need to perform fetch on my NSFetchedResultsController
Here's my code:
override func viewDidLoad() {
super.viewDidLoad()
let fetchRequest = NSFetchRequest(entityName: "Photograph")
//fetchRequest.predicate = self.predicate
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "primaryKey", ascending: true)]
let ctx = RKObjectManager.sharedManager().managedObjectStore.persistentStoreManagedObjectContext
let frc = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: ctx,
sectionNameKeyPath: nil,
cacheName: nil)
do {
try frc.performFetch()
} catch {
let fetchError = error as NSError
print("\(fetchError), \(fetchError.userInfo)")
}
self.manager.storage = CoreDataStorage(fetchedResultsController: frc)
self.manager.startManagingWithDelegate(self)
self.manager.registerNiblessCellClass(GalleryImageCell)
}
Got this little ditty from the compiler as it threw an runtime exception
Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (10) must be equal to the number of items contained in that section before the update (10), plus or minus the number of items inserted or deleted from that section (10 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).
Now i recall a year or so back running into the same problem when working with UICollectionViews and i did come up with a solution but it escapes me, luckily i believe someone else documented their struggles and solutions on the same problem.
any change of an update or would you like me to make a pull request? I wont be able to do so myself for a few days at least...Work deadlines and such.
In your method:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView <DTModelTransfer> *view = nil;
id supplementary = nil;
if ([self.storage respondsToSelector:@selector(supplementaryModelOfKind:forSectionIndex:)])
{
supplementary = [self.storage supplementaryModelOfKind:kind forSectionIndex:indexPath.section];
}
if (supplementary)
{
view = [self.factory supplementaryViewOfKind:kind
forItem:supplementary
atIndexPath:indexPath];
[view updateWithModel:supplementary];
}
return view;
}
If no reusable view was registered, you will return nil. Since IOS7 it's create a crash.
How can I specify that I want a certain supplementary view to show up in a certain section of the collectionView?
Maybe i am missing where in the docs I can do this
e.x
Section 1 = HeaderViewOne
Section 2 = HeaderViewTwo
.
.
.
Section n = HeaderViewN
Currently I'm not using nibs nor storyboard, thus I just call registerCellClass:
. When the CollectionView tries to dequeue a cell it raises an exception saying that no cell class has been registered.
The fix is easy, I just need to call collectionView?.registerClass(CellClass.self, forCellWithReuseIdentifier: "<reuse identifier that would be generated with reflection>")
from my view controller.
This kind of stuff could go in the library itself, in my opinion. Also because if one day you change identifier, my code breaks.
What do you think?
Before I open a PR, I'd like to know if it would be enough to add the code above to an else
clause in the registerCellClass:
method or if there's no else
clause because that's needed for storyboards compatibility: if no nib exists it means that the view is in the storyboard?
If that's the case, I propose to handle the pure (code only) case in the method registerCellClass:
and add a new method registerCellClassWithNoStoryboardNorNib:
that has the current implementation (suggestions for method names are appreciated!!).
(I'll obviously update the cousin registerSupplementaryClass: forKind:
method)
Hi! Thanks for great lib
How to listen UIScrollViewDelegate methods?
class: DTCollectionViewManager.swift
method: open func startManaging(withDelegate delegate : DTCollectionViewManageable)
line 204: guard let collectionView = delegate.collectionView ?? delegate.optionalCollectionView else {
preconditionFailure("Call startManagingWithDelegate: method only when UICollectionView has been created")
}
DTCollectionViewManager/DTCollectionViewManager.swift:204: Fatal error: Call startManagingWithDelegate: method only when UICollectionView has been created
2021-07-04 19:12:51.399824+0200 Doctorate[2073:95370] DTCollectionViewManager/DTCollectionViewManager.swift:204: Fatal error: Call startManagingWithDelegate: method only when UICollectionView has been created
In order to use DTCollectionViewManager
i'm trying to implement desired functionality in my DTCollectionViewController
sub-class. However, I can not add @IBOutlet
for collectionView
.
What is best practice?
The following code:
@IBOutlet var collectionView: UICollectionView!
gives me compiler error:
Property 'collectionView' with type 'UICollectionView!' cannot override a property with type 'UICollectionView'
Setter for 'collectionView' with Objective-C selector 'setCollectionView:' conflicts with setter for 'collectionView' from superclass 'DTCollectionViewController' with the same Objective-C selector
I would like to have a collection where the main section is FRC-based, but other sections are in-memory items. Is this possible?
Hi, could you help me, I want to get access to previous model when I use coredata as storage.
I need get access to previous model in manager.configure closure
updateWithModel() has an only parameter for the data model. How can I get the indexPath for the cell? UICollectionView#indexPathForCell doesn't work cause it returns nil when the cell is not visible.
DTCollectionViewManager#configureCell() doesn't get called on cell's dequeuing.
CollectionViewManager crashes when it checks if it shouldReloadCollectionViewToPreventInsertFirstItemIssueForUpdate
In particular, I'm asynchronously adding new items to the manager:
private func contentLoaded(resources: [Container]?, error: ErrorType?) {
print("content loaded")
if resources != nil {
manager.memoryStorage.addItems(resources!)
}
}
The manager then checks:
for indexPath in update.insertedRowIndexPaths {
if self.collectionView.numberOfItemsInSection(indexPath.section) == 0 {
shouldReload = true
break
}
}
And crashes when calls self.collectionView.numberOfItemsInSection(indexPath.section)
(in that moment, there were 0 sections with 0 items).
Removing those lines make the app work correctly.
I run the app on the iOS 9 Simulator.
Exception logged:
*** Assertion failure in -[UICollectionViewData numberOfItemsInSection:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UICollectionViewData.m:566
2015-10-02 17:48:42.212 Sales App[82499:1913317] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for number of items in section 0 when there are only 0 sections in the collection view'
I was trying to do something where I was calling configure
twice on the same cell class.
Looking at the configure
code, it calls a routine named appendReaction
, which made me think that I could do this. Ordering of the two blocks doesn't matter. But I noticed, while stepping through, that delegateWasReset
gets called when the reaction is appended. The end result is that the second configure
block is not called.
Anyway, just wondering if 2 configure blocks can be added to the same cell-class, and if so, how? If not, then I just need to know that.
Scrolling and reusing items seems to work fine when there are no sections present, but as soon as I add one, the list get laggy and jumpy. Also, the second section somehow overlaps some of the items.
The code (in a view, inside awakeFromNib):
manager.registerHeader(TimeHeader.self) { $0.condition = .section(0) } manager.registerHeader(TimeSectionHeader.self) { $0.condition = .section(1) } storage.setSectionHeaderModel(TimeHeaderModel(), forSection: 0) storage.setSectionHeaderModel(TimeSectionHeaderModel(timeDay: .monday), forSection: 1)
Then I'm simply adding models to storage as usual.
There's is a known issue with UICollectionView, that crashes application if reloadData call was sent prior to performBatchUpdates method.
Radar: https://openradar.appspot.com/28167779
Known workarounds - in terms of DTCollectionViewManager:
MemoryStorage
or CoreDataStorage
SectionModel
level of abstraction.CollectionViewUpdater
, that calls reloadData
instead of calling performBatchUpdates
, however this will cost you animations, that will not be performed.Any help or ideas how to implement maintainable solution are welcomed!
For example layout:
_layout = [UICollectionViewFlowLayout new];
_layout.scrollDirection = UICollectionViewScrollDirectionVertical;
_layout.minimumLineSpacing = 10.f;
_layout.minimumInteritemSpacing = 0;
const CGFloat kHeaderHeight = 25.0f;
_layout.headerReferenceSize = CGSizeMake(self.collectionView.width, 50.f);
Methods -
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewFlowLayout *)collectionViewLayout
referenceSizeForHeaderInSection:(NSInteger)sectionNumber
{
BOOL supplementaryModelNotNil = NO;
if ([self.storage respondsToSelector:@selector(supplementaryModelOfKind:forSectionIndex:)])
{
supplementaryModelNotNil = ([self.storage supplementaryModelOfKind:UICollectionElementKindSectionHeader
forSectionIndex:sectionNumber]!=nil);
}
return supplementaryModelNotNil ? collectionViewLayout.headerReferenceSize : CGSizeZero;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewFlowLayout *)collectionViewLayout
referenceSizeForFooterInSection:(NSInteger)sectionNumber
{
BOOL supplementaryModelNotNil = NO;
if ([self.storage respondsToSelector:@selector(supplementaryModelOfKind:forSectionIndex:)])
{
supplementaryModelNotNil = ([self.storage supplementaryModelOfKind:UICollectionElementKindSectionFooter
forSectionIndex:sectionNumber]!=nil);
}
return supplementaryModelNotNil ? collectionViewLayout.footerReferenceSize : CGSizeZero;
}
Will never get called, so trick with CGSizeZero will not help, and app will crash.
Hi!
I have one image in each cell and while scrolling collection view lags. Scrolling collection view jams loading cells.
Any solution for this?
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.