Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Chirone

macrumors 6502
Original poster
Mar 2, 2009
279
0
NZ
I want to change the order of subviews on a view and found the method sortSubviewsUsingFunction:context and found out how to use it.

the problem is that whenever i call it, the subviews keep flipping order.
so, subview1 which should be behind subview2 will become in front and then when the method is called again they'll switch so that subview1 is behind subview 2

i'm calling the method similar to this:
Code:
- (IBOutlet)reorderSubViews:(id)sender {
[baseFocusView sortSubviewsUsingFunction:(NSComparisonResult (*)(id, id, void*))compareViewDepth context:NULL];
}
and the comparison method is like so:
Code:
int compareViewDepth(id firstView, id secondView, void *context) 
{
	SpecialView *first = (SpecialView*)firstView;
	SpecialView *second = (SpecialView*)secondView;
	if([first.controller.z intValue] == [second.controller.z intValue]) {
		return NSOrderedSame;
	}
	if([first.controller.z intValue] < [second.controller.z intValue]) {
		return NSOrderedAscending;
	}
	return NSOrderedDescending;
}

why does it reorder things differently each time?
as far as i can tell it's quite the same as what you see in this thread here: http://www.cocoabuilder.com/archive/cocoa/119585-sortsubviewsusingfunction-question.html
 

Chirone

macrumors 6502
Original poster
Mar 2, 2009
279
0
NZ
the z values are just NSNumbers that are ints (NSNumber because it came from core data)
the first subview will have z = 0
the second will have z = 1
etc

the return of compareViewDepth appears to always be correct. (there are two copies of each view for some reason though and thus two views with the same z value, but that surely shouldn't be relevant though..)

for example, when i print out subviews i will get something like this:
(
"<SpecialImageView: 0x114589140>",
"<SpecialImageView: 0x114582770>",
"<SpecialTextBoxView: 0x115006270>",
"<SpecialTextBoxView: 0x114587cf0>",
"<SpecialTextBoxView: 0x115032b80>",
"<SpecialTextBoxView: 0x11504c070>"
)

as it enters the compareViewDepth method i had it print out the z values of the two views it's comparing and print out what it will return..

<SpecailImageView: 0x114589140> 1 < <SpecailImageView: 0x114582770> 1
same
<SpecailImageView: 0x114582770> 1 < <SpecailTextBoxView: 0x115006270> 0
descending
<SpecailImageView: 0x114589140> 1 < <SpecailTextBoxView: 0x115006270> 0
descending
<SpecailTextBoxView: 0x114587cf0> 0 < <SpecailTextBoxView: 0x115032b80> 2
ascending
<SpecailTextBoxView: 0x114587cf0> 0 < <SpecailTextBoxView: 0x11504c070> 2
ascending
<SpecailTextBoxView: 0x115032b80> 2 < <SpecailTextBoxView: 0x11504c070> 2
same
<SpecailTextBoxView: 0x115006270> 0 < <SpecailTextBoxView: 0x115032b80> 2
ascending
<SpecailTextBoxView: 0x115006270> 0 < <SpecailTextBoxView: 0x11504c070> 2
ascending
<SpecailTextBoxView: 0x115006270> 0 < <SpecailTextBoxView: 0x114587cf0> 0
same
<SpecailImageView: 0x114589140> 1 < <SpecailTextBoxView: 0x114587cf0> 0
descending

and then I'll print out the subviews again and it'll be in reverse order.

if i trigger the method again it will compare the views but they are switched and returning the opposite result as before
for example
<SpecailImageView: 0x114589140> 1 < <SpecailTextBoxView: 0x114587cf0> 0
descending
on the next time through will be
<SpecailTextBoxView: 0x114587cf0> 0 < <SpecailImageView: 0x114589140> 1
ascending

is this what you meant?
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
"<SpecialTextBoxView:0x115006270>",
"<SpecialTextBoxView:0x114587cf0>",

"<SpecialImageView:0x114589140>",*
"<SpecialImageView:0x114582770>",

"<SpecialTextBoxView:0x115032b80>",
"<SpecialTextBoxView:0x11504c070>"

1
----

"<SpecialTextBoxView:0x115006270>",
"<SpecialTextBoxView:0x114587cf0>",

"<SpecialImageView:0x114589140>",*
"<SpecialImageView:0x114582770>",

"<SpecialTextBoxView:0x11504c070>"
"<SpecialTextBoxView:0x115032b80>",

2
---


"<SpecialTextBoxView:0x115006270>",
"<SpecialTextBoxView:0x114587cf0>",

"<SpecialImageView:0x114582770>",
"<SpecialImageView:0x114589140>",*

"<SpecialTextBoxView:0x115032b80>",
"<SpecialTextBoxView:0x11504c070>"

3
----

"<SpecialTextBoxView:0x115006270>",
"<SpecialTextBoxView:0x114587cf0>",

"<SpecialImageView:0x114582770>",
"<SpecialImageView:0x114589140>",*

"<SpecialTextBoxView:0x11504c070>"
"<SpecialTextBoxView:0x115032b80>",

4
----



"<SpecialTextBoxView:0x114587cf0>",
"<SpecialTextBoxView:0x115006270>",

"<SpecialImageView:0x114589140>",*
"<SpecialImageView:0x114582770>",

"<SpecialTextBoxView:0x115032b80>",
"<SpecialTextBoxView:0x11504c070>"

5
----

"<SpecialTextBoxView:0x114587cf0>",
"<SpecialTextBoxView:0x115006270>",

"<SpecialImageView:0x114589140>",*
"<SpecialImageView:0x114582770>",

"<SpecialTextBoxView:0x11504c070>"
"<SpecialTextBoxView:0x115032b80>",

6
---

"<SpecialTextBoxView:0x114587cf0>",
"<SpecialTextBoxView:0x115006270>",

"<SpecialImageView:0x114582770>",
"<SpecialImageView:0x114589140>",*

"<SpecialTextBoxView:0x115032b80>",
"<SpecialTextBoxView:0x11504c070>"

7
----

"<SpecialTextBoxView:0x114587cf0>",
"<SpecialTextBoxView:0x115006270>",

"<SpecialImageView:0x114582770>",
"<SpecialImageView:0x114589140>",*

"<SpecialTextBoxView:0x11504c070>"
"<SpecialTextBoxView:0x115032b80>",

8
----


So those are the 8 possible orders from lowest to highest. Can you get more information about what each view is (set their values? Colors?) to try to track the duplicates?

Note that when your function is called, what should be returned is based on the order of the arguments. The example you gave should be fine.

When does Z get set? Is it automatic? Will changing the order change the z value?

-Lee
 

Chirone

macrumors 6502
Original poster
Mar 2, 2009
279
0
NZ
The z value is given when the view is created. it so far it stays the same (although essentially it's meant to change, and reorder is meant to shuffle the order of the views based on that, but that's not yet implemented as i just wanted to get the ordering part right first..)


I made a quick experimental project that does the same thing as my bigger project in regards to the reordering.
It does the same thing.
I don't like putting projects up because people who do seem like they're saying 'here's my code, now fix it' without ever bothering to try work through the problem first...
But i have tried figuring this out, but there must be something i'm missing so i'm attaching the little experimental project if you're curious

I create a view called the focusView and add that to the main window. Then I create two subviews for that and add them.
There is a menu item at the top called reorder which just called the sortSubviewsUsingFunction method.
This project also keeps alternating the order of the subviews.

what you see in this project is basically the same as what is in the bigger project (the bigger one has more classes that the z value is buried in)
 

Attachments

  • OrderingExperiement.zip
    28.8 KB · Views: 69

chown33

Moderator
Staff member
Aug 9, 2009
10,743
8,417
A sea of green
Change your sort function so it never returns NSOrderedSame.

I don't know what sorting algorithm is being used, but if it's not stable, you'll get things at the same level flipping around unpredictably (a characteristic of unstable sorts). FWIW, some common sorts are unstable: e.g. quicksort.

It shouldn't matter what criteria you use for maintaining stability, as long as it's stable. Sounds tautological, and it is. I'd just compare object pointers if Z values are identical: it's simple and stable, so it should tell you whether sort stability is causing the problem. (After re-reading, I don't think this is the cause of the problem. Sorting should still be stabilized, though.)


I'm wondering what triggers a re-sort in your app.

If you're accidentally causing an inversion, i.e. sort reversal, because of some event equivalent to clicking on the sort-key column, then the standard interpretation of that is to reverse that column's sort order. You can see this in almost any app that has sorted columns, such as the List view of Finder, where clicking a column (say Name) that's already the sorting key will reverse the sort.

Find out what's causing calls to reorderSubViews:.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.