Is it possible to force collectionView not to reuse visible cells? - uicollectionview

dequeueReusableCellWithReuseIdentifier doc says: "This method dequeues an existing cell if one is available .." When is a cell available? How can I force collectionView not to reuse cells that are visible?
Could it help, if for indexPath I pass a nil argument?

NOT the visible cells get reused, but the ones which where visible, but at the moment are off-screen.
This is how the Guidelines tells us to do!!!
Reusable Views Improve Performance.
"Collection views employ a view recycling program to improve efficiency. As views move offscreen, they are removed from view and placed in a reuse queue instead of being deleted. As new content is scrolled onscreen, views are removed from the queue and repurposed with new content."
Check out this link to understand better:
https://developer.apple.com/Library/ios/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CollectionViewBasics/CollectionViewBasics.html

Related

UICollectionView: cellForItemAt isn't called properly

I'm trying to make a UICOllectionView with a stack of subviews, with the possibility to add and delete different subviews.
The problem is that cellForItemAt is not called properly. E.g. numberOfItemsInSection is set to 4 so I would expect 4 subviews. However, cellForItemAt is not called for all items, only for visible, and it is being called only when I scroll through this UICollectionView. Is there any way to call it for all items at once ?
Another problem is that after scrolling through UICollectionView to the end it adds additional subview, which corresponds to one of the previous subviews.
So it is not clear, why cellForItemAt is called as soon as all items were shown. And how it choses indexPath.row for this additional item.
The last strange thing is that cellForItemAt is being called once again as I scroll back , so it adds subviews to the cells which already have some subviews so that they are stacked one above another:
It seems, that the way UIcollection works is completely different from principles in UITableView
UICollectionView isn't that different really to UITableView really.
'cellForItemAt' is called each time a cell is about to become visible so on first load it will only be called for your visible cells, which is the behaviour your seeing. As you scroll through it will be called for each cell as they appear. This makes it more memory efficient as cells are reused and only created when needed.
I'm not sure you can force it to load all cells initially without a bit of hacky code to either scroll the collection view yourself or programatically call the code you want yourself. Without understanding your implementation better this probably isn't what you want.
The additional cellForItem call when you scroll to the end is probably due to the collection view 'bouncing' on the last cell and reloading a previous one due to the animation. Also 'indexPath.row' should probably be replaced with 'indexPath.item' for collection views but this shouldn't really affect your implementation.

MKMapView blocks main thread while used in UITableView

I have a basic UITableView that contains 20 cells, one of the cells is a MKMapView just dropped in as is without any custom code (not even setRegion:Animated), if I open the view at the first time and scroll down the table view (towards the map's cell), there is a noticeable hang happens for the app, and if I use setRegion:Animated (without dropping any pin) the hang gets longer. However, this block of the main thread disappears on later attempts to scroll towards the map's cell.
I can't use the MKSnapShotter because I want the user to interact with the map so an image won't satisfy the case.
the table view does not make any block on the main thread if the map does not exist.
how to avoid blocking the main thread while showing the map's cell for the first time ?
First make a tableView IB outlet if you haven't already done so. Create the cell in view did load using tableView.dequeueReusableCellWithIdentifier("mapCellIdentifier") and store that in an ivar. Then in the data source return the cell when the index path is the one you want so inside of cellForRowAtIndexPath do
if (indexPath.row == wantedRow) {
return mapCell
}
The mapCellIdentifier needs to be set in the cell you created in interface builder for the map. This is assuming you have dynamic cells.

Strategy for measuring performance of an iOS app

I have a simple case of an iOS application I would like to measure: a UITableView built with custom extended cells. Each cell is a composition of a main views and some subviews. Based on some criteria I am hiding or showing subviews in table cell.
Supposing I have to decide if adding subviews when needed, or built xib with all the outlets and hide/show when needed.
What could be the best approach for deciding between those two ?
Supposing also you didn't read Apple guidelines about composition of cell, what concrete steps you would do either via code (by putting NSLog statement for example), or via Xcode instruments (which one to choose etc...) to confirm the choice.
This is quite a new matter for me, so please be as much specific as you can.
This http://blog.giorgiocalderolla.com/2011/04/16/customizing-uitableviewcells-a-better-way/ is a great resource.
Having many subviews with transparent backgrounds degrades scrolling performance.
Dynamically adding subViews could get difficult to track, and if you don't do it "right" then you'll end up with cells with too many "extra" subviews, via the cell reuse queueing mechanism.
You'll have to add the subViews in the init method of the cell itself and not in the cellForRow method of your data source. (unless you're using some way to track the creation/availability of any given subview, like viewWithTag etc.)

Prevent updates to NSFetchedResultsController whilst table view is in edit mode

I am using an NSFetchedResultsController with a data source that is updated in the background. This is working really well - as new objects are saved to the managed context they appear in the UITableView. However, this leads to the problem I'm having.
When you swipe to delete a cell, putting the cell into edit mode, if at that point an object is created which pushes the cell down in the table view, the position which the cell occupied will be in edit mode, and not the cell you selected. Basically, the UITableView retains the edit mode on the original index path, without adjusting for the movement of cells.
Is there any way to get around this? Thus far everything I've tried has lead to a dead end.
reminds me of a problem i had when reordering uitableview cells.Look at 'Responding to changes' in NSFetchedResultsController reference. It shows a way to temporarily disable the change notification. I used it for reordering, maybe you can get inspiration from it to solve your problem too.
kind regards
y

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.