Make a deep copy of a UIView and all its subviews - objective-c

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?

Related

NSTableView problems - displaying custom TableView from with a SplitView panel

I am developing my first app for OSX. Sorry for asking stupid questions. I have spent a few hours trying to figure this out on my own, with no luck so far.
I want to make an iTunes-like interface. I used NSSplitView, placed NSView for navigation and NSTableView above that. [I am aware that there better alternatives to NSSplitView, yet my goal is to both - develop an app and also to learn Cocoa/OSX in the process.]
Atop NSView panel designated for navigation, I am trying to place NSTableView. However, my table is not being displayed. I therefore have questions...
I understand that for cells to be populated, controller must implement NSTableViewDataSource. I tried that, but was so far unsuccessful - to the point that I don't see the table. Please advise:
Can I have a working NSTableView-derived custom class also implementing NSTableViewDataSource? If this cannot work, please advise why or point me to an explanation.
Am I correct in thinking that all elements can be manipulated programmatically, in the sense that I use IBOutlet in headers to point to the right object, yet do nothing with InterfaceBuilder - have everything controlled from within my Objective-C code? Do I have to use IB?
Thank you.
Yes that will work but it's an unusual approach. Generally the tableview delegate/datasource is something enclosing the tableview. You'd normally only subclass NSTableView if you require some additional functionality not provided by default (for me that has been custom behaviour to input).
Yes you can do it all programmatically, however you will find it much easier to use IB. The IB-loaded views are created programmatically under the hood, using the information contained in the nib file. You will find it long-winded and tedious pretty quickly.
WRT to your issue with not seeing the table, you will need to add logging/breakpoints on the few key delegate/datasource methods to ensure they are being called (start with the daddy of them all numberOfRowsInTableView:). If they are not then you aren't setting the delegate/datasource correctly in the tableview.

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

Apply dequeueReusableCellWithIdentifier to a bunch of UIImageViews not TableviewCell

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 -

NSOutlineView elements remain hopelessly undraggable

I have a program with a NSOutlineView (that supports single selection only) from which I'd like to be able to drag elements. These elements should either be received as text or files: for instance, dropping the item on a TextEdit window should put text, but dropping the item on the Finder should create a file. I don't want anything to be dropped over my outline view, even it it comes from itself. This seems easy enough, but for some reason, I can't get it to work.
I checked the NSOutlineView drag and drop example from Apple, and I came to implement the following methods (plus a few definitely unrelated ones):
-(BOOL)outlineView:shouldSelectItem: // I don't expect to drag unselectable items
-(NSArray*)outlineView:namesOfPromisedFilesDroppedAtDestination:forDraggedItems:
-(BOOL)outlineView:writeItems:toPasteboard:
However, when I try to drag an item from my outline view, nothing happens. Instead, it just changes the selection following the cursor.
I've put breakpoints in the two last methods, and they never get called, so their implementation is not the immediate issue.
I must be missing something really obvious here.
Also, this is not (yet) a problem, but how am I supposed to provide contents to my promised files?
I was being stupid and I implemented the methods in the delegate instead of the data source (the two are distinct in my app). Problem solved!
Are you using a custom table view cell? The result of NSCell's hitTestForEvent:inRect:ofView: determines whether a dragging operation can be initiated. It also determines whether your outlineView:writeItems:toPasteboard: should be called.
This method should return NSCellHitContentArea to initiate a drag, or NSCellHitTrackableArea to extend or change the selection.
A standard text cell returns NSCellHitContentArea when you click on the actual text of the cell, and NSCellHitTrackableArea when you click outside of the text. This produces the drag behavior you see in Finder's table view.
You can override this method and always return NSCellHitContentArea if you want all areas of the cell to initiate a drag operation.
See Hit Testing for more information.

UIImageView on top of another UIImageView, changeing layers

Afternoon, I have a UIImageView that I progmatically add to the window. Infact I have multiple UIImageViews that do so and when I click on any specific UIImageView I want it to become 'top-dog' so to say and be drawn over all other objects on the screen. Basically like the priority drawing for MSWindows operating systems when it comes to their windows. I've scoured all the options built in for UIImageViews when it comes to layering but I cannot seem to find any! I know it exists because in UIBuilder there is a command for sending back/front toBack/toFront. How do I access these progmatically?
Edit*
Also I fear that you might have to access the order in which the subViews are pushed into the 'subView stack' and manually move these around to achieve the result that I want and if so, how would I go about doing this?
Edit2*
Perhapse these are the functions I'm looking for?
bringSubviewToFront
sendSubviewToBack
exchangeSubviewAtIndex
Does this allow for easy Index shuffling?
UIView class has bringSubviewToFront: and sendSubviewToBack: for changing subviews z-order (see "Managing the View Hierarchy" section in class reference for more).