Most efficient way to hide a UIView - cocoa-touch

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.

Related

Custom control with and without autolayout

I will be creating a custom control (based on UIView).
Is there a way it could work with UIViewControllers using auto layout as well as UIViewControllers that do not?
The control should work in both cases. The difference is that in one case you will use constraints to layout it and in the other one, setting the frame programmatically.
If your control contains other subviews, it is important how you configure these. For example, if you do the setup of the subviews in initWithFrame: and you use the given frame to layout them (meaning static frames, instead of constraints), in the auto layout viewControllers, the frames will no get updated.
However, layouting the subviews with constraints will have no impact on the non-autolayout viewControllers. The subviews will have the layout according to your constraints, in the given static frame of the custom control.
It is a general explanation since I don't know that much about your particular controller. Hope this makes sense and you can find helpful.

NSTableView: Displaying An Expanded Row (Resizing on the Fly)

OK. I looked through the suggestions (which often answer my questions before I ask). I haven't found what I need.
I know that I'm doing something wrong. I do this all the time in iOS (UIKit), but tables in NS (Mac) are pretty darn different from UIKit.
I have a view-based NSTableView. Each row has exactly 1 column. This column has a view with a header (21 points high), and an expanded view (the row is 420 points high). There is a disclosure triangle on the left of the header that toggles these two modes.
The controller is also the table datasource and delegate. I have the row height callback returning the correct values for the view.
The header displays fine. I set the row heights to 21, and only the headers are shown. This clips the main view.
When a disclosure triangle is toggled, a row expands its height to reveal the entire view:
Simple enough, eh?
The problem is that B is not displayed. I just get a blank (However, A is correctly displayed). The items are there, just not being displayed. The table row is the correct height (this can be verified by using alternating row colors).
I've tried setting setNeedsLayout/Draw on the views.
Any clues on what I may be doing wrong?
I'm willing to bet that I'm doing something boneheaded, and I'll keep looking into this.
Using noteHeighOfRowsWithIndexesChanged:? It's an NSTableView function, not a delegate function.
In the documentation for the delegate function tableView:heightOfRow it declares:
Although table views may cache the returned values, you should ensure that this method is efficient. When you change a row's height you must invalidate the existing row height by calling noteHeightOfRowsWithIndexesChanged:. NSTableView automatically invalidates its entire row height cache when reloadData and noteNumberOfRowsChanged are called.
As it mentions, NSTableView's reloadData is often the lazy way to fix your sort of issue as well.
Your table controller shouldn't need the setsNeeds[whatever] methods you tried.
Also, speaking of disclosure triangles and such, on OSX there is a NSTableView subclass called NSOutlineView that handles item expansion if you mangle your data into a poorly documented tree format. I actually wouldn't recommend it if your data's not a natural tree, but you should be aware of it, even if its API sucks. Oh, and the expansion when clicking the disclosure triangle is animated.

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.

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

How to bring an NSImageView to the front or back of another NSImageView?

I have a NSTableView that holds a name to all of my NSImageView's, and depending on the order that the NSImageViews were added, the last one would be in the front.
But in the case that I want the user to be able to bring a NSImageViews in front of another, how would I do that?
Thanks in advance.
As explained on the NSView reference page, the z-order of a view's subview is given by their oder in the view's subviews array. You can insert a new subview relative to the others using -addSubview:positioned:relativeTo:, and you can reorder the existing subviews by getting the subviews property, reordering the views therein as you like, and then calling -setSubviews: to set the new order.
Specifically, the docs say:
The order of the subviews may be considered as being back-to-front,
but this does not imply invalidation and drawing behavior.
What you are asking about, I think, is how to control the z-order of views.
For historical performance reasons this is not well supported in AppKit (unlike UIKit in iOS), since until somewhat recently you couldn't actually have sibling views that overlap.
A common approach to this (on recent OS X releases) is to use Core Animation (in particular, CALayer) which does support z-ordering natively, but this is probably overkill for what you need (and in any event is going to have a learning curve for you).
What are you actually trying to do? Are these images (image views) precisely on top of one another? If so, the easiest (and much better performing) approach is to have a single NSImageView and to just send -setImage:... to it to change the displayed image.