views:

163

answers:

3

Hi all,

I have a NSMutableArray that holds a collection of UIViewControllers

Amongst other properties and methods an instance of each of the viewControllers are placed in a parent view

The user will place these objects individually when desired to.

So essentially I use - (void)addSubview:(UIView *)view when a new view is added to the parent view controller.

Because the UI is isometric it's made things a tad more complicated

What I am trying to do is re-order the views based on their co-ordinate position, so items higher up the parent UIView frame is indexed lower then views lower in the parent UIview frame. And items that are on the left side of the view are positioned at a higher index to those on the right

I think the solution may have to do with re-ordering the NSMutableArray but how can I compare the CGpoints? Do I need to compare the x and y separately?

A: 

So users can drag views around inside a parent view? And when a view changes position, you want to change its place index among the subviews so that the draw order will be correct?

You can use -(void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2 do do this. It won't be enough to just reorder them in you array, since the parent UIView has its own array to keep track of the views. You should create a reorder method where you switch the views around both in your own array and in the parent view.

There are functions for checking equality of points, inclusion of points in rects, intersection of rects, etc, but here it just sounds like you want to get the origin.y point and use that to compare which views are further "back" or to the front...

As an aside, you might want to look at using CALayers, which have support for setting a z position as well.

Felixyz
Yes users can drag the views as they desire, it's already setup to detect other views so they don't overlap and such, I've almost finished building this class and it's the actual index order giving me a bit of grief. I'll have a look at the CALayers class to see if that helps.Also, if you can maybe answer this, exchangeSubviewAtIndex seems potentially useful but the ViewController views are added dynamically, I can't see a property for the index value of a view, do I track this manually? Cheers
Chris
exchangeSubview... is defined on UIView. There is no way, as far as I know, of getting the index of a view, but you could maybe use tag and viewWithTag: to keep the view ordering synchronized with your own array. But again, layers will probably work better for you, and will give you better performance and more flexibility in creating animations and effects if you want to do that.
Felixyz
Thanks, I only just read this - I was thinking along similar lines, I've managed a solution involving taking the tags and re-ordering them. There is also a key piece of info I failed to mention in my question but I'll still look into CALayers if it could potentially help with performance as I think it might be a bit heavy in the way I've done it. Cheers!
Chris
A: 

This might be a simplistic answer, but maybe it's what you're looking for.

Assuming you have access to their CGpoints, you could write a...

-(NSComparisonResult) compare: (NSObject *) incoming;

method in every delegate that looked at the CGpoints of the incoming and "self" and returned a NSComparisonResult. Cool thing about this would be that you could just run...

[myMutableArray sortUsingSelector:@selector(compare:)];

anytime anything changed. You just have to setup the compare: method to return the right NSComparisonResult.

Staros
Thanks for this, I'll have to read up on NSComparisonResult, this seems useful
Chris
A: 

I've managed to resolve this, I did some reading on Key-Value Coding

I created a property called itemY to store the view.frame.origin.y value.

I created a method to re-assign the itemY with the current view.frame.origin.y value.

Now the ViewController that stores the array of ViewControllers uses a instance NSSortDescriptor with the property itemY.

A new NSArray is created using the NSSortDescriptor

Now I loop through the new NSArray and carry out my logic

Chris