2

I have a parent UIView with several subviews.

The subviews are siblings - the child-views are not sub views of each other. (Each at the same heirarchical level in their superview)

For instance:

UIView *containerView = [[UIView alloc] initWithFrame:frame];
CustomUIView *childView = [[UIView alloc] initWithFrame:anotherFrame];
CustomUIView *yetAnotherChildView = [[UIView alloc] initWithFrame:anotherFrame];

[containerView addSubview:childView];
[containerView addSubview:yetAnotherChildView];

[containerView bringSubviewToFront:childView];

I want yetAnotherChildView to be able to detect it was moved back in the view heirarchy. How can this be done?

Edit:

I understand that the containerView can know what subviews are above what - but I don't wan't (can't) the containerView notify its subviews that their order changed - Imagine adding a subview ontop of a stock view - the stock view has no idea of its subviews and that they would like to receive such a notification.

The subview CustomUIView would need to observe some change in its superview

for instance (this probably is a very bad solution)

CustomUIView

-(id)initWithFrame
{
  [self.superView addObserver:self forKeyPath:@"subViews" options:options context:context];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
 // if keyPath is "subViews" array check if "this" view is ontop and adjust self accordingly
}
Avba
  • 14,822
  • 20
  • 92
  • 192

3 Answers3

1

Check their indices in view.subviews array. The one with low index will be at top. So the view at 0 index will be at the top of all others.

Abid Hussain
  • 1,529
  • 1
  • 15
  • 33
  • I want the subview to detect it was sent back. I don't want to explicitly notify it that it was moved back. Imaging a case where a view has some animation happening when it is visible. When it isnt' visible I want to stop the animation. The subview would need some mechanism of knowing that its "z" index is out of sight (below another view) – Avba Jan 29 '14 at 14:22
  • Ok. so only one view will be on top (in superview)? – Abid Hussain Jan 29 '14 at 14:29
  • In this particular case yes - but it could be generalized – Avba Jan 29 '14 at 14:32
  • I think it's the contrary. The view with the lowest index (ie 0), is behind all others. – Vinzius Jun 02 '14 at 11:40
1

You can scan through containerView.subviews and find which one is on which position. If you want to do it on every addSubview - subclass your containerView and add your own addSubview which calls parent class implementation and after that emits notification that subviews array changed (or just do checks right there). In notification handler you can scan through subviews and do whatever you want with order.

Oleg Fedorov
  • 337
  • 3
  • 10
1

Try this it will give you all views behind given view

-(NSMutableArray *)getAllViewsBehindView:(UIView *)view{
NSMutableArray *tempArr = [NSMutableArray array];

NSArray *subViews = view.superview.subviews;

for (int i = 0; (i < subViews.count); i++)
{
    UIView *viewT = [subViews objectAtIndex:i];

    if (viewT == view)
    {
        return tempArr;
    }
    else
    {
        if (CGRectIntersectsRect(viewT.frame, view.frame))
        {
            [tempArr addObject:viewT];
        }
    }

}

return tempArr;}
Rajesh Choudhary
  • 1,340
  • 8
  • 12