8

I need to detect which view is in front (currently visible). How can I do this?

Here is a what I would like to do:

if ( ! <<methodToTellIfViewAIsInFront>>) {
  [viewA prepareToDisplay];
  [window bringSubviewToFront: viewA];
}
Andrew Raphael
  • 507
  • 2
  • 7
  • 9

7 Answers7

14

UIView's don't necessarily have a concept of being in front. UIWindows can be key or not, but it's not quite the same thing.

You can bring a view to the front, but that doesn't mean it is or is not visible. Remember, views can be any size.

A UIView buried deep in the hierarchy could be partially visible, it could be obscured, or it could be behind some translucent view. Likewise a view at the front may not be visible at all if its opacity value or hidden flags are modified.

I think what you want to do is check the subviews NSArray of your superview or UIWindow and check that. I can't remember which is the front, but it is either the first or last object.

Subviews are drawn with the painter's method. The views are drawn in order from farthest to nearest and the last object drawn is "the front."

amattn
  • 10,045
  • 1
  • 36
  • 33
5

The following will return YES if viewA is in front:

[[viewA.superview.subviews lastObject] isEqual: viewA]
Lucas Chwe
  • 2,578
  • 27
  • 17
  • 1
    This worked like a charm, here it is in swift fyi: http://stackoverflow.com/questions/1536923/determine-if-uiview-is-visible-to-the-user/36875529#36875529 – teradyl Apr 26 '16 at 22:00
4

Check if [UIView.window isKeyWindow] == YES

Cherpak Evgeny
  • 2,659
  • 22
  • 29
  • This won't tell you if a view is actually visible, but it tells you if the window to which the view belongs is the current key window. – ff10 Jan 18 '13 at 10:22
2

Add this to view controller:

- (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
 visible = YES;
}

- (void)viewWillDisappear:(BOOL)animated {
 visible = NO;
 [super viewWillDisappear:animated];
}

and check 'visible' ivar

dimzzy
  • 247
  • 2
  • 6
  • 1
    use self.window != nil, spare the bool. – steipete Sep 01 '11 at 16:59
  • This might not help. I have a case here, in which "viewDidAppear" is being called, but the view is actually not visible. – auco Mar 22 '12 at 14:26
  • 4
    These methods won't help, because they are only called when the view is being added to/removed from the view hierarchy, not when the view is being made visible/invisible. – Paul Schifferer Sep 02 '12 at 21:30
1

Answer of @LucasChwe in Swift 4

if viewA.superview?.subviews.last == viewA { 'viewA is visible to user'}
iOS Lifee
  • 2,091
  • 23
  • 32
0

The only way to do it is to assign a unique identifier to your view using [UIView tag] and then use [UIView viewWithTag] to bring it to the front.

Or you can search for the view you need using the tag and work on it..

for (UIView *checkView in [self.view subviews] ) {
      if ([checkView tag] == whatever) {
      // Do Whatever you need to do
      }
}

..then bring it to front.

Cheers

Jordan
  • 21,746
  • 10
  • 51
  • 63
-1

When dealing with modal views, this code worked with me in my root view controller:

 if(self.view == [(MyAppDelegate *)[[UIApplication sharedApplication] delegate].window.subviews objectAtIndex:0]){ ... 
          // stuff here 
     }
avance
  • 1,993
  • 2
  • 21
  • 23