【问题标题】:How to check if a specific UIViewController's view is currently visible? [duplicate]如何检查特定 UIViewController 的视图当前是否可见? [复制]
【发布时间】:2011-04-10 08:12:06
【问题描述】:

可能重复:
How to tell if UIViewController's view is visible

我正在开发一个应用程序,它处理来自网络的持续传入数据流,并提供许多不同的 UIView 供用户查看这些数据。

当基于来自网络的传入流更新某些模型数据时,我访问关联的 UIViewController 或 UITableViewController 并对其执行 -setNeedsDisplay(在 UIViewController 的情况下)或 -reloadData(在 UITableViewController 的情况下)。

有没有办法检查给定的 UIView 当前是否正在显示(不仅仅是正在加载),以便我只在用户当前正在查看该 UIView 时执行 -setNeedsDisplay 或 -reloadData?似乎在用户当前未查看的视图上调用 -setNeedsDisplay 或 reloadData 会浪费处理能力并且不利于电池寿命。当用户最终切换到之前已更新的视图时,对 -viewWillAppear 执行 -setNeedsDisplay 或 reloadData 会更有意义。

谢谢

【问题讨论】:

标签: iphone objective-c


【解决方案1】:

在做了一些研究之后,我在此处发布的另一个问题中找到了这个答案...这似乎是最好的方法...

如果视图当前可见,则视图的 window 属性为非 nil,因此请检查视图控制器中的主视图:

if (viewController.isViewLoaded && viewController.view.window){
    // viewController is visible
}

【讨论】:

  • 我刚刚编辑了the other question 以首先检查 isViewLoaded 以避免意外加载上面这段代码将执行的视图。进行测试:if (viewController.isViewLoaded && viewController.view.window) ...
  • 这个答案不应该被真正标记为正确,因为它会触发加载 VC 的视图。请参阅上面链接的程序员的答案。
  • 这会给你误报的 viewControllers 被其他模态显示的 viewControllers 阻碍 -> 不是正确的方式。这样做是对 viewController 的可靠检查是不可见的,但反之亦然。
  • 从技术上讲,这个答案仅表明视图位于窗口的视图层次结构中。它没有说明该特定视图的真实可见性(可以从屏幕上移开、设置隐藏或被子视图隐藏...)
  • 评论是您的代码示例具有误导性。当然,在某些情况下,您的所有 IF 条件都为真并且 viewController 不可见。例如,如果应用程序是后台的。
【解决方案2】:

将此添加到您的控制器或 UIViewController 的子类中,然后您可以进一步子类化。使用属性或变量访问它:

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

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

【讨论】:

  • 另外,不要将此作为一个类别。在一个类别中重新定义方法是不好的做法。
  • 这将是一个类别的灾难,因为您将无法定义要在 viewDidAppear 或 ViewWillAppear 上发生的任何特定于类的行为。
  • 当然,您仍然可以定义特定于类的行为。您可以覆盖方法并仍然调用超级方法。虽然这是一篇旧帖子,但我发现类别没有用,因为您需要存储 visible。我会编辑它。
  • 在这里使用实例变量并不是最好的解决方案。像上面 Paul 建议的无状态解决方案要好得多。
【解决方案3】:

为了完整起见,我想我会添加如何确定视图控制器是否显示在基于选项卡的应用程序中:

+(BOOL) isSelectedViewController:(UIViewController *)someVC;
{
    myAppDelegate   *appD = [[UIApplication sharedApplication] delegate];
    UIViewController *selectedVC = [appD.TabBarController selectedViewController];

    return selectedVC == someVC;
}

【讨论】:

  • 如果您在标签栏控制器中嵌套导航控制器,使用 (myViewController.tabBarController.selectedViewController == myViewController.navigationController) 会更好。
  • 我想如果您知道子控制器是导航控制器,但通常情况并非如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多