Two UICollectionView instances sharing the same UICollectionViewFlowLayout instance? - objective-c

I'm not sure if this is a feature or a bug, but when I have two collection views on a view controller using the same instance of UICollectionViewFlowLayout, an interesting thing happens. Note that I'm not using Interface Builder / XIBs for any of this; I'm laying everything out in code.
The first UICollectionView has twelve cells in it, but the second one has 20. When I reload both collection views, both act as if their contentSize property has 20 cells in it. This means that when I scroll to the right of the first UICollectionView and get past the first (and only) 12 cells, my app crashes (because I'm pulling data from an array that only has 12 cells' worth of data).
To get around this for now, I'm instantiating two identical UICollectionViewFlowLayout objects and assigning each to its own collection view. Is this normal behavior?
I'm only getting started writing code with UICollectionViews, so forgive my ignorance if I'm exuding any!

Don't do this. A collection view and a layout object should be a 1:1 relationship. The layout object has a property, collectionView, which obviously can only hold a reference to one collection view.
When the collection view then asks the layout for its size and so forth, the layout object is going to base everything on the second collection view you assigned the layout to, since this will be held in the collectionView property.
I couldn't find an explicit statement in the docs not to share a layout object between collection views, but the property discussed above should make it clear that this is not an intended use.

Related

NSCollectionView cell order changes on view change

I have a macOS application that contains a tab bar design (ie: Tweetbot). There are 4 tabs that are linked to 4 different view controllers. The initial view controller (view one) contains a NSCollectionView which displays 3 cells horizontally.
This all works fine, however when I switch to another view controller and then come back to the initial view controller, the order of the collection view changes for no reason. I am not making ANY changes to the data source (which is a NSMutableArray) and I am not adding/deleting any cells, nor am I calling reloadData. I don't understand why the order of the collection view cells keep changing.
I have done some testing and can confirm that the order of the data in my data source, does NOT change at all. So it makes no sense for the collection view, to just change the order of the cells.
Another weird issue I have noticed, is that if I limit the collection view to 2 cells, this issue does not occur. This makes me wonder whether or not, the issue is down to some sort of NSCollectionView caching method that runs in the background? Perhaps when the collection view recycles a cell, it uses the incorrect data??
I have tried lots of different solutions, nothing seems to work. Does anyone have any ideas of what I can test/try out, in order to find out what's wrong?
Alternative idea
I could use NSTableView instead, because it supports multiple columns (unlike UITableView). So I could just make an NSTableView with 3 columns. Would this approach be any worse performance wise, than a NSCollectionView (especially if I wanted to add lots of cells?).
I couldn't find out what was wrong with the collection view. So I ended up using a NSTableView with multiple columns (instead of collection view rows). I set each column to have one row (index 0), which makes the table view look exactly like the collection view I was working with.
Performance wise the table view seems to be a lot better too. Even with hundreds of columns, it's still nice and smooth when scrolling/interacting.

iOS 7 settings like DetailViewController

I have a simple project that was started from a Master/Detail template for iOS7.
I'd like to layout the detail view controller just like iOS settings. Do folks recommend using a table for that or just laying out the controls one by one?
Here is a screenshot of the effect I am looking for:
This is probably a matter of taste/opinion but I prefer tables for this kind of thing for these reasons:
You get all the nice features of tables right out of the box (efficient scrolling, cell reuse and delegate methods to handle where to push new view controllers on to the stack, etc...).
Flexible data model backed cell data. Your table view needs to be backed by some "settings" model object collection, obviously. That collection can be modified to include or exclude settings programmatically. Combine this with custom cells and you're off and rolling. This is really nice if your UI needs to change on the fly.
Code Reuse. If you have another set of "settings" you can use this data-backed table view approach and change only your data model. Doing this manually means you have a new view controller for every settings view. In your example picture, I'd bet my lunch that the 3 view controllers you see in that image are the same type of object.
The table's delegate methods are really helpful when segueing or pushing to new view controllers. Imagine having 10 settings that all took you to separate view controllers. You'd have to manually hook those transitions one by one, yuck.
Of course if you only have 1-2 settings that will never change, perhaps manual is the way to go. For my money, though, tables make sense because things like this always seem to change.

How to Reload NSCollectionView

I have NSCollectionView with full of items, have one scenario where after deletion of one item the collection view should be refresh and it should display update items.
I am able to delete item, but collection view is not refreshing,
googled a lot, but got nothing,
NSCollectionView is a subclass of NSView. And you must be knowing MVC design pattern. View is intended only to show the data/values from the model.
In your case you must have some array. You need to update the array and set the content of NSCollectionView programmatically or using Cocoa Bindings.
- (void)setContent:(NSArray *)content;
Also you may need to refresh the view :
[yourCollectionView setNeedsDisplay:YES]
Anoop's suggestion didn't work for, but following did, copied from here
Turns out that the NSCollectionView item views can be refreshed by setting the ItemPrototype, e.g.,
ItemPrototype = new SomeViewController()
This causes all the existing views to be recreated.

iOS 6.0 UICollectionView - same cells being added multiple times

While using collection view, in cellforItemAtIndexPath, new cell instance is being added multiple times (on top of another) at same location/frame, even though correct reuseidentifier is being passed to "dequeueReusableCellWithReuseIdentifier:forIndexPath:"
The cell mentioned above is a subclass of UICollectionViewCell and contains UITextField with proper frame. When scrolling and textfield is first responder, the above said problem is occurring.
Please let me know of any pointers to address the issue.
This could be a bug in UICollectionView related to one I've already filed with decoration views. As long as your cells are opaque, it should not affect your interface
It's possible (though, imo, not very likely) that this is correct behaviour for UICollectionView and it uses those extra cells for interface orientation. At any rate, the problem seems much less pronounced that the one with decoration views, which would add dozens of copies of the decoration view. As long as it's not affecting your app, I'd say live with it.

NSTableView. How to override autoscroll behavior?

I've got an NSTableView that displays (via bindings) data from an NSTreeController. The application frequently appends/changes data to/in the bound array.
The problem is that if the user has selected a row in the table, but has scrolled so that the selected data is no longer visible, when the application updates the array it causes the display to auto-scroll so that the selected line is once again on screen. This is pretty
frustrating to users, especially since new data can arrive at any time.
Is there any way of disabling this feature?
You may have to subclass NSTableView and override -scrollRowToVisible:, temporarily bracketing the call to super. This may also require a custom BOOL ivar in your subclass to keep track of whether you want to scroll.
I would start by setting a breakpoint there to see when exactly the autoscroll is triggered. This should help to find the proper moments to toggle the ivar.
Are you using an NSTreeController with an NSOutlineView or an NSArrayController with an NSTableView? Using an NSTreeController with an NSTableView doesn't make a lot of sense to me?
If you're using an NSTableView you should probably be using an NSArrayController to manage its data and this rearranging of the rows is a feature of the NSArrayController. Try turning off the Auto Rearrange Content option on your controller within IB.
When it's on, the array controller will rearrange its objects on addition, removal and changes to objects that would affect the sort ordering (if any) and cause any table views or outline views to reload their data.
I don't know of a similar feature for NSTreeController mainly because I don't use it since it's never worked well for me. I, sadly, recommend to just use the datasource methods for the NSOutlineView and supply your data the old-fashioned way. In my experience, NSTreeController is only well suited for the most trivial tasks.