IOS:如何将某些视图放在已呈现的模态视图控制器之上?

24

我在AppDelegate类中添加了一个活动视图到选项卡栏:

[self.mainTabBar.view addSubview: spinner];

当存在连接问题时,每个视图控制器中都会显示旋转的加载图标。 某些视图控制器中有一个按钮,用于呈现某个模态视图控制器。 该模态视图控制器会覆盖在加载图标上方。如何让这个加载图标始终处于所有视图或至少在该模态视图控制器之上? 我在呈现模态视图控制器的视图控制器中尝试了这样的操作:

[self presentModalViewController:selectionViewController animated:YES];
[self.view bringSubviewToFront:[self.tabBarController.view viewWithTag:15]];

不起作用。

5个回答

65
将视图添加到主窗口。
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview: spinner];

10
虽然这样做无法正确响应方向的更改。为了解决这个问题,您需要使用类似UIView *view = mainWindow.subviews [0]; [view addSubview:spinner]这样的内容。 - Ray Fix
你刚刚解决了我的(有点不相关的)问题,谢谢! - bpiec
好的,但是如何从另一个过程中删除它,@phix23? - new2ios
@new2ios 你可以给视图打上唯一的标识符,以便在窗口的视图层次结构中再次找到它。 - Felix
stackoverflow上的最佳答案 - Viet Nguyen

12

尽管 phix23 的回答是正确的,这里提供了一个更完整的例子:

//The view you want to present
UIViewController *viewControllerYouWantToPresentOnTop = [[UIViewController alloc] initWithNibName:nil bundle:nil];

//Create transparent host view for presenting the above view
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
UIViewController *viewControllerForPresentation = [[UIViewController alloc] init];
[[viewControllerForPresentation view] setBackgroundColor:[UIColor clearColor]];
[[viewControllerForPresentation view] setOpaque:FALSE];
[mainWindow addSubview:[viewControllerForPresentation view]];

//Make your transparent view controller present your actual view controller
[viewControllerForPresentation presentViewController:viewControllerYouWantToPresentOnTop animated:TRUE];

当您不再需要这些东西时,请记得清理干净。

即使是一个库,这段代码也可以从您的应用程序的任何地方使用 :)


到目前为止,这是我发现的最好的,但这会导致“未平衡调用开始/结束外观转换”。 - meaning-matters
@meaning-matters 你同时还有其他动画吗?你可能需要等待它们完成。 - Maciej Swic
很抱歉,没有其他动画了。感谢您快速回复,@Maciej。 - meaning-matters
尝试使用这个代码:UIViewController *viewControllerYouWantToPresentOnTop = [[UIViewController alloc] initWithNibName:nil bundle:nil]; 替换第一行。 - Maciej Swic
这正是我寻找了六个多小时的答案。真正解决了我的问题。谢谢。 - Abhinav
显示剩余2条评论

4

一般情况下,应用程序在其生命周期内会在一个窗口中显示其内容。但是,在某些情况下,可能需要使用额外的窗口在其他所有内容之上添加内容。苹果通过将 UIAlertView 添加到单独的窗口中来确保它始终处于最上层。

UIView *contentView = [[UIView alloc] initWithFrame:contentFrame];
contentView.backgroundColor = [UIColor greenColor];
UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(x,y,contentFrame.size.width, contentFrame.size.height)];
window.windowLevel = UIWindowLevelAlert;
[window addSubview:contentView];
[window makeKeyAndVisible];

通过设置window.hidden = Yes或No来显示或隐藏窗口。 这将始终在应用程序中的所有其他内容上显示您的contentView


1

模态控制器位于完全不同的层中,您无法使呈现控制器的任何子视图重叠它。

使用带有旋转器的UIAlertView。警报显示在一个层中,即使是模态控制器也会被覆盖。


这是不正确的。虽然警告视图在其他所有内容的顶部有一个单独的层,但模态框不是,并且可以使用我下面发布的代码被覆盖。 - Maciej Swic
@MaciejSwic 我知道如何将子视图添加到窗口,注意我的答案是指“呈现控制器的任何子视图”。使用 UIAlertView 在技术上是更好的解决方案。 - Sulthan

0
将视图放置在keyWindow上,如上所建议。您可能还需要将模态视图的演示样式设置为当前上下文,否则它仍然可能会弹出到顶部。

其他答案并不总是“在上面”。当你输入答案时,它们确实是在上面的 - 但是一旦发布后,它们就会按页面排序。标准包括“趋势”,“最高分”,“修改日期”,“创建日期”。根据这些参数,您的答案将被放置在页面上。 - Eric Aya

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