Apply dequeueReusableCellWithIdentifier to a bunch of UIImageViews not TableviewCell - objective-c

Im not sure if this is possible but I was just hoping to have a question answered about dequeueReusableCellWithIdentifier and if it could be applied to something other than a UITableViewCell. Maybe not dequeueReusableCellWithIdentifier exactly, but maybe something along the same idea.
I have a bunch of UIImageViews, that appear in a grid, they all have the same image, and the user can remove and add more to the grid so it is quite dynamic. But I was hoping that maybe there would be a way to reuse some of the images that the user has removed, because I'm seeing some pretty large performance issues after the user interacts with them for a little while.
Can anyone give me a little advice how I might do this?

There's no built-in mechanism, but it's not hard to create one.
Just add an NSMutableArray to your view controller. Every time you remove a view from the grid because it's moved off screen add it to the array. Every time you need to add a new view to the grid, check the array and see if there are any views in it. If there are, remove one from the array and add it to the screen. If there aren't, create alloc a new view.
That's really all there is to view dequeing and re-use.
You don't need to replicate the reuseIdentifier stuff because (I'm guessing) all the views in your grid will be the same class.
If you do need to have multiple different views, just have multiple queue arrays and use different arrays for different view types.

Why dont you create one UITableViewCell & add 2 ImageViews on them. Dont forget to add a unique cell identifier to them o that dequeueReusableCellWithIdentifier works as usual.
Something like this -

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.

Most efficient way to hide a UIView

Out of the following, which is the best way to hide a view?
Setting frame to CGRectZero
Hidden Property to YES
alpha Property to 0.0
Does one have benefits that the other does not? In terms of saving resources at runtime? Specifically in a UITableView with reusable cells where some subviews may not be needed by one cell versus another.
It depends on what you want/need to accomplish. For views that will likely be reused alot, a combination of view.hidden=TRUE (my choice for this case) and/or view.alpha=0.0, and maybe manipulate the z-index to make sure your view is no longer at the front.
I am not sure about the benefit of setting the view's frame to CGRectZero, it might be more appropriate to remove the entirely at that point.
In short, if you don't need it, don't keep it.
UPDATE:
With the mention table cells, also consider the possibility of creating multiple custom cells, especially if removing subviews causes layout problems. Each cell can be created based on whatever criteria you have set.
UPDATE 2:
Based on a comment left below, if the cells are complex, drawing the cell via code may be the right solution.
With UIView's, alpha=0 has the advantage of being animatable whereas hidden=YES does not. frame=CGRectZero is also animatable but is quite a different effect. When animating alpha=0.0 will cause the view to fade out whereas frame=CGRectZero will cause it to appear to vanish into the upper left. I wouldn't worry about the system resource expense of any of these techniques as they're all pretty lightweight.

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.)

UITableView: how to make it not recycle cell?

Is there a way to make table view not recycle UITableViewCell so after all cells are loaded, it won't ask for cells(ie tableView:cellForRow...)?
I know I can put the table view in a scroll view and make the table view to have the same size as the scroll view, so all cells will be loaded, but some of my cells have variable sizes, then I need to update the scroll view's content size after the cells' sizes are changed.
Is there any other way to do this?
update:
Sorry for the misleading, actually I mean how to make it not REMOVE cells once created, so if there are ten cells, and there won't be any cell returned by dequeueReusableCell and after ten tableView:cellForRow: it won't call it again.
Simply not use reusable identifier will make it create new cell every time as needed, even the cell at position 1 has been created but then reused for position 2.
Set the reuseIdentifier to nil.
This is much better than using a different identifier for each cell, as the table can now dispose unneeded cells quickly. If they have some identifier set, there's no way to tell if you will ever reuse them.
So you don't have to miss the reuse part completely, just for the cells you don't want to. If the new cell contains the same subviews (maybe just layout and configured differently) - it might still be better to reuse.
Just don't use a cellIdentifier, or use a different identifier for each cell.
just dont use - (id)dequeueReusableCellWithIdentifier:(NSString *)identifier
in the cellForRowAtIndexPath method and create a new cell everytime.
Other way is to give a different cell Identifier for each cell you create.
Now, If you can elaborate on why you dont want the tableview to recycle its cells (which is one of the powerful feature of tableview), may be you can find out other ways to achieve the same thing with reusing the cells..!!
Hope it helps..:)

Make a deep copy of a UIView and all its subviews

I need to make a deep copy of a UIView containing several subviews. Please help me figure out how to do this? I've done some searching on google and SO and not found anything that does what I want.
Explanation for those who would like to know why: I have an infinitely scrolling UIScrollView where, of course, the contents repeat. Each 'set' of the contents (for example, say 26 UIButtons labeled A-Z) is contained inside one view. This is the view I need to make a deep copy of, so that I can display multiple instances of it onscreen within the scrollview.
I cannot simply recreate the structure of the view containing the buttons, because pressing the buttons calls a function of a class that my UIScrollView subclass does not have access to. Nor would I wish to recreate them, because it seems a waste to go through the logic to recreate and place all subviews in the container view when I could simply make a deep copy instead.
Can anyone help me?
(Posted from my comment on request)
Aha right I see now. I think the only way would be to create more copies at runtime and hide them; else you'd have to iterate through all subviews, re-create all frames, colors etc... but as you say you'd then likely run into issues copying button targets etc - but there might be something useful to help accomplish that here:
How to get UIButton Target, Action and Control events?