如何判断一个UIView是否在前面(可见)?

8

我需要检测哪个视图在前面(当前可见)。我该怎么做?

这是我想要做的:

if ( ! <<methodToTellIfViewAIsInFront>>) {
  [viewA prepareToDisplay];
  [window bringSubviewToFront: viewA];
}

https://dev59.com/GXE85IYBdhLWcg3wbTD1#2777460 - LolaRun
为什么不试试 if(view.isHidden) { } 呢? - DD_
7个回答

14

UIView并没有明确的“在前面”的概念。UIWindows可以是关键或非关键,但这不完全相同。

您可以将视图带到最前面,但这并不意味着它可见或不可见。请记住,视图可以是任何大小。

在层次结构中深埋的UIView可能部分可见,可能被遮挡,也可能在一些半透明视图后面。同样,如果修改了其不透明度值或隐藏标志,位于前面的视图可能根本不可见。

我认为您想要做的是检查父视图或UIWindow的子视图NSArray,并检查那个。我记不清哪一个是在前面,但它是第一个或最后一个对象之一。

子视图使用绘画师方法绘制。从最远处到最近处按顺序绘制视图,最后绘制的对象是“前面”。


7
对于UIView来说,其subviews数组中的第0个子视图是最靠后的一个,在它下面以此顺序绘制其他的子视图。 - Brad Larson
1
我正在调试以检查子视图,并发现最后一个子视图是在前面的那个。 - Andrew Raphael
感谢您的跟进,Brad和Andrew。 - amattn

5
如果viewA在前台,以下代码将返回YES:
[[viewA.superview.subviews lastObject] isEqual: viewA]

1
这个方法非常好用,以下是它在 Swift 中的实现:https://dev59.com/XnI_5IYBdhLWcg3wEe1u#36875529 - teradyl

4

检查[UIView.window isKeyWindow]是否等于YES


这并不会告诉你一个视图是否真正可见,但它会告诉你该视图所属的窗口是否是当前关键窗口。 - ff10

2

将以下内容添加到视图控制器中:

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

并检查“visible”实例变量。


1
使用self.window != nil,避免使用bool。 - steipete
这可能没有帮助。我这里有一个情况,其中“viewDidAppear”被调用,但实际上视图并不可见。 - auco
4
这些方法无法帮助,因为它们只会在视图被添加到/移除出视图层次结构时调用,而不会在视图变得可见/不可见时调用。 - Paul Schifferer

1

@LucasChwe在Swift 4中的答案

if viewA.superview?.subviews.last == viewA { 'viewA is visible to user'}

0
唯一的方法是使用 [UIView tag] 为视图分配一个唯一标识符,然后使用 [UIView viewWithTag] 将其置于前面。
或者,您可以使用标记搜索所需的视图并对其进行操作。
for (UIView *checkView in [self.view subviews] ) {
      if ([checkView tag] == whatever) {
      // Do Whatever you need to do
      }
}

...然后将其置于最前面。

干杯


-1

当处理模态视图时,这段代码在我的根视图控制器中有效:

 if(self.view == [(MyAppDelegate *)[[UIApplication sharedApplication] delegate].window.subviews objectAtIndex:0]){ ... 
          // stuff here 
     }

如果窗口没有子视图,这段代码既不能回答问题,又会导致崩溃。 - Legoless

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接