iOS账号框架嵌入Unity后登录界面被遮挡的问题及代码疑问
我开发了一款用于管理游戏账号(登录、登出、注册等)的原生iOS框架,将其导入Unity项目后,调用框架方法显示登录界面时,界面虽被present,但却处于presenting view controller下方。
相关实现代码如下:
- (void)showViewController:(UIViewController *)controller { UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:controller]; nav.navigationBarHidden = YES; [nav setModalPresentationStyle: UIModalPresentationOverCurrentContext]; [[UIViewController topMostController] presentViewController:nav animated:YES completion: nil]; } + (UIViewController*) topMostController { UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topController.presentedViewController) { topController = topController.presentedViewController; } return topController; }
topMostController返回的是UnityDefaultViewController(同时也是keyWindow的rootViewController),传入showViewController的是我的SigninViewController,为何登录界面会被UnityDefaultViewController遮挡?该框架此前已导入多个Unity游戏,这是首次出现此问题。
[更新]排查代码后发现,疑似Unity引擎生成的如下代码导致了该问题:
- (void)showGameUI { ... [_window addSubview: _rootView]; //this line cause the issue _window.rootViewController = _rootController; [_window bringSubviewToFront: _rootView]; ... }
能否确认这些代码由Unity引擎生成?我尝试注释[_window addSubview: _rootView];这一行后问题解决,且暂未发现其他问题,这样操作是否可行?
解答
代码归属确认
这段showGameUI中的代码确实是Unity引擎生成的,属于iOS平台下Unity窗口管理的核心逻辑,一般出现在Unity导出iOS项目的UnityAppController相关类文件中。遮挡原因分析
Unity手动将_rootView(游戏画面视图)添加为window的子视图,随后调用bringSubviewToFront:把它强制置顶。而你通过present方式弹出的登录界面,虽从UnityDefaultViewController(rootViewController)发起,但由于_rootView被直接挂载到window层级且被置顶,会覆盖所有视图控制器的视图(包括模态弹出的登录界面)——因为默认情况下,视图控制器的视图层级依附于rootViewController,直接添加到window的子视图优先级更高。注释该行的可行性
注释[_window addSubview: _rootView];是完全可行的,理由如下:
- 当设置
_window.rootViewController = _rootController;时,iOS系统会自动将_rootController的视图(即_rootView)添加到window的子视图层级中,Unity的手动添加属于冗余操作,反而会造成层级混乱。 - 你测试后未发现其他问题,说明这个冗余操作在当前项目中没有特殊作用。Unity的这种写法可能是为了兼容iOS 6及更早版本,但当前主流iOS版本仅设置rootViewController就足够完成视图挂载。
若你的项目无需兼容iOS 6及以下版本,注释该行后不会有任何问题;后续若Unity版本更新,导出代码可能变化,需重新验证该修改的有效性。
内容的提问来源于stack exchange,提问作者Tiến Nguyễn Hữu

