首先添加一个 UIView,甚至是导航栏
Posted
技术标签:
【中文标题】首先添加一个 UIView,甚至是导航栏【英文标题】:Add a UIView above all, even the navigation bar 【发布时间】:2014-03-18 00:13:51 【问题描述】:我想在任何其他视图甚至导航栏上方显示一种“弹出”视图,如下所示:
带有 0.5 alpha 的全屏黑色背景可以看到下面的另一个UIViewController
。
中间有一个 UIView
窗口,其中包含一些信息(如果您想了解所有信息,可以使用日历)。
为此,我创建了一个 UIViewController,其中包含两个 UIViews
(背景和窗口),并且我正在尝试显示它。我尝试了一个简单的[mySuperVC addSubview:myPopUpVC.view]
,但我仍然有上面的导航栏。
我尝试将其呈现为模态,但下方的 UIViewController
消失了,我失去了透明效果。
任何想法,我相信这很简单......
谢谢!
【问题讨论】:
在您的应用程序窗口中添加子视图。处理方向变化可能很棘手:***.com/questions/8774495/… 【参考方案1】:在 Swift 4.2 和 Xcode 10 中
var spinnerView: UIView? //This is your view
spinnerView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
//Based on your requirement change width and height like self.view.bounds.size.width
spinnerView?.backgroundColor = UIColor.black.withAlphaComponent(0.6)
// self.view.addSubview(spinnerView)
let currentWindow: UIWindow? = UIApplication.shared.keyWindow
currentWindow?.addSubview(spinnerView!)
在目标 C
UIView *spinnerView;//这是你的视图
self.spinnerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height)];
//Based on your requirement change width and height like self.view.bounds.size.width
self.spinnerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
// [self.view addSubview:self.spinnerView];
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:self.spinnerView];
这可以在纵向或横向模式下工作。
更简单的代码是:
yourViewName.layer.zPosition = 1//Change your view name
【讨论】:
【参考方案2】:您可以通过将视图直接添加到 keyWindow 来做到这一点:
UIView *myView = /* <- Your custom view */;
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:myView];
更新 -- 适用于 Swift 4.1 及更高版本
let currentWindow: UIWindow? = UIApplication.shared.keyWindow
currentWindow?.addSubview(myView)
适用于 iOS13 及更高版本的更新
keyWindow
已弃用。您应该使用以下内容:
UIApplication.shared.windows.first(where: $0.isKeyWindow )?.addSubview(myView)
【讨论】:
谢谢 :) 不幸的是,如果您处于横向模式,您需要旋转视图。我不确定我是否知道如何正确地做到这一点。 是的,我只处于横向模式,myView 以 90 度旋转出现。似乎是他们在这里谈论的内容:***.com/questions/8774495/… 方向问题发生在 ios8 之前的设备上,遗憾的是这个解决方案不起作用。 @NicolasRoy Autolayout 会有所帮助 它不覆盖标签栏。有什么解决办法吗?【参考方案3】:您需要在第一个窗口中添加一个 UITextEffectsWindow 类型的子视图。首先,因为自定义键盘添加了它们的 UITextEffectsWindow,如果你向它添加子视图,这将无法正常工作。 此外,您不能将子视图添加到最后一个窗口,因为例如键盘也是一个窗口,您不能从键盘窗口呈现。 所以我找到的最好的解决方案是将子视图(甚至推送视图控制器)添加到具有 UITextEffectsWindow 类型的第一个窗口,该窗口涵盖附件视图、导航栏 - 一切。
let myView = MyView()
myView.frame = UIScreen.main.bounds
guard let textEffectsWindow = NSClassFromString("UITextEffectsWindow") else return
let window = UIApplication.shared.windows.first window in
window.isKind(of: textEffectsWindow)
window?.rootViewController?.view.addSubview(myView)
【讨论】:
【参考方案4】:已检查响应的 Swift 版本:
斯威夫特 4:
let view = UIView()
view.frame = UIApplication.shared.keyWindow!.frame
UIApplication.shared.keyWindow!.addSubview(view)
斯威夫特 3.1:
let view = UIView()
view.frame = UIApplication.sharedApplication().keyWindow!.frame
UIApplication.sharedApplication().keyWindow!.addSubview(view)
【讨论】:
我可以让它覆盖所有当前视图(视图控制器),但让新出现的视图控制器显示在它上面吗?【参考方案5】:如果您只想显示您的自定义视图,@Nam 的答案非常有用但如果您的自定义视图需要用户交互,您需要禁用navigationBar
的交互。
self.navigationController.navigationBar.layer.zPosition = -1
self.navigationController.navigationBar.isUserInteractionEnabled = false
就像在 Nam 的回答中所说的那样,不要忘记扭转这些变化:
self.navigationController.navigationBar.layer.zPosition = 0
self.navigationController.navigationBar.isUserInteractionEnabled = true
您可以通过扩展以更好的方式做到这一点:
extension UINavigationBar
func toggle()
if self.layer.zPosition == -1
self.layer.zPosition = 0
self.isUserInteractionEnabled = true
else
self.layer.zPosition = -1
self.isUserInteractionEnabled = false
然后像这样简单地使用它:
self.navigationController.navigationBar.toggle()
【讨论】:
完美解决方案.. !!尝试了很多东西并花了很多时间..但这很好..!!【参考方案6】:UIApplication.shared.keyWindow?.insertSubview(yourView, at: 1)
此方法适用于 xcode 9.4、iOS 11.4
【讨论】:
【参考方案7】:请注意,如果您想在全屏模式下添加视图,请仅使用以下代码
添加UIViewController
的这些extensionpublic extension UIViewController
internal func makeViewAsFullScreen()
var viewFrame:CGRect = self.view.frame
if viewFrame.origin.y > 0 || viewFrame.origin.x > 0
self.view.frame = UIScreen.main.bounds
继续正常添加子视图
现在用于添加UIViewController的viewDidAppear
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
self.makeViewAsFullScreen()
【讨论】:
【参考方案8】:这是一个对我有用的简单优雅的解决方案。您可以将导航栏的z位置设置在视图下方:
self.navigationController.navigationBar.layer.zPosition = -1;
记得在完成后将其设置回 0。
【讨论】:
这比将覆盖视图作为子视图添加到导航控制器的视图(顺便说一下会导致崩溃)要好得多。这种 z 位置解决方案可能更可靠,并且在未来引起的问题更少。 这在处理故事板时非常有用。您可以在情节提要中添加视图! 对我也很有效。很高兴提到 zPosition 应该设置回值 0(您只是提到它应该在完成后设置回来)。而且我有 tabBar(在我的屏幕上也来自 TabBarController。我尝试设置 zPosition 但是当返回 0 值时 tabBar 仍然不可见。所以对于 tabBar 最好使用 isHidden 属性。 不要使用辅助功能。平移视图不会使其聚焦。【参考方案9】:[self.navigationController.navigationBar.layer setZPosition:-0.1];
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(10, 20, 35, 35)];
[view setBackgroundColor:[UIColor redColor]];
[self.navigationController.view addSubview:view];
[self.navigationController.view bringSubviewToFront:view];
self.navigationController.view.clipsToBounds = NO;
[self.navigationController.navigationBar.layer setZPosition:0.0];
【讨论】:
【参考方案10】:[[UIApplication sharedApplication].windows.lastObject addSubview:myView];
【讨论】:
【参考方案11】:@Nicolas Bonnet 答案的 Swift 版本:
var popupWindow: UIWindow?
func showViewController(controller: UIViewController)
self.popupWindow = UIWindow(frame: UIScreen.mainScreen().bounds)
controller.view.frame = self.popupWindow!.bounds
self.popupWindow!.rootViewController = controller
self.popupWindow!.makeKeyAndVisible()
func viewControllerDidRemove()
self.popupWindow?.removeFromSuperview()
self.popupWindow = nil
不要忘记窗口必须是一个强属性,因为原来的答案会导致窗口立即释放
【讨论】:
【参考方案12】:将您的视图添加为 NavigationController 的子视图。
[self.navigationController.navigationBar addSubview: overlayView)]
您也可以在窗口上添加它:
UIView *view = /* Your custom view */;
UIWindow *window = [UIApplication sharedApplication].keyWindow;
[window addSubview:view];
希望这会有所帮助.. :)
【讨论】:
Over view 即将到来,但是,当添加按钮时无法获得按钮操作或在 overView 上设置自定义标签文本 对我来说很好:let navigationBar = viewController.navigationController!.navigationBar navigationBar.addSubview(coverView)
【参考方案13】:
我会使用 UIViewController 子类,其中包含嵌入其他视图控制器的“容器视图”。 然后,您就可以在 Container View 中添加导航控制器(例如使用嵌入关系 segue)。
见Implementing a Container View Controller
【讨论】:
【参考方案14】:Dalef 在 swift 中的绝佳解决方案:
self.navigationController?.view.addSubview(view)
【讨论】:
【参考方案15】:有不止一种方法可以做到这一点:
1- 在UIWindow
上添加您的UIView
,而不是在UIViewController
上添加它。这样一来,它将凌驾于一切之上。
[[(AppDelegate *)[UIApplication sharedApplication].delegate window] addSubview:view];
2- 使用自定义过渡,让你的 UIViewController 以 0.5 alpha 显示在后面
为此,我建议您查看以下内容:https://github.com/Citrrus/BlurryModalSegue
【讨论】:
【参考方案16】:[self.navigationController.view addSubview:overlayView];
是你真正想要的
【讨论】:
你需要设置框架 非常好的解决方案,尤其是当您将视图添加为“子视图控制器”时 这不适用于子视图控制器的视图。更改导航栏的 z 级别(如 Nam 建议的那样)也适用于子视图控制器。 它看起来是一个比向 Key 窗口添加视图更优雅的解决方案。因为这确保了添加视图,所以沿着基本视图的动画移动。因为如果在关键窗口上添加视图,它不会附带动画,如果您想关闭控制器,则必须单独删除。 这不是弹出窗口,但它对我来说是正确的事情。谢谢))【参考方案17】:我建议你创建一个新的 UIWindow:
UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
window.rootViewController = viewController;
window.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
window.opaque = NO;
window.windowLevel = UIWindowLevelCFShareCircle;
window.backgroundColor = [UIColor clearColor];
[window makeKeyAndVisible];
然后你可以在另一个 UIViewController 中管理你的视图。 移除窗户:
[window removeFromSuperview];
window = nil;
希望对您有所帮助!
【讨论】:
谢谢,但我认为缺少一些东西,因为什么都没有出现:/以上是关于首先添加一个 UIView,甚至是导航栏的主要内容,如果未能解决你的问题,请参考以下文章
在 UITabBarController 中的标签栏和导航视图之间添加 UIView