首先添加一个UIView,甚至是导航栏

我想在任何其他视图,甚至是导航栏上,显示一种“弹出”视图,看起来像这样:

  • 全屏黑色背景,0.5 alpha,可以看到下面的另一个UIViewController
  • 中间有一个UIView窗口,里面有一些信息,(如果你想知道所有的信息,一个日历)。

为此,我创建了一个UIViewController,其中包含两个UIViews(背景和窗口),我试图显示它。我已经尝试了一个简单的[mySuperVC addSubview:myPopUpVC.view],但我仍然有上面的导航栏。

我试图将它表示为一个模态,但下面的UIViewController消失了,我失去了透明效果。

有什么办法可以做到这一点吗,我相信这很简单……

谢谢!

158132 次浏览

你可以通过将你的视图直接添加到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)

我建议你创建一个新的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;

希望对大家有所帮助!

将您的视图添加为NavigationController的子视图。

[self.navigationController.navigationBar addSubview: overlayView)]

你也可以把它加在窗户上:

UIView *view = /* Your custom view */;
UIWindow *window = [UIApplication sharedApplication].keyWindow;
[window addSubview:view];

希望这能有所帮助。:)

[self.navigationController.view addSubview:overlayView];是你真正想要的

做这件事的方法不止一种:

1-在UIWindow上添加你的UIView,而不是在UIViewController上添加它。这样的话,它就会在一切之上。

   [[(AppDelegate *)[UIApplication sharedApplication].delegate window] addSubview:view];

2-使用自定义过渡,将保持你的UIViewController显示在后面的0.5 alpha

为此,我建议你看看这个:https://github.com/Citrrus/BlurryModalSegue

Dalef伟大的解决方案在swift:

self.navigationController?.view.addSubview(view)

这里有一个简单的优雅的解决方案,是为我工作。你可以将导航栏的z位置设置为视图的下方:

self.navigationController.navigationBar.layer.zPosition = -1;

只要记住在完成时将其设置为0即可。

我将使用一个UIViewController子类,包含一个“容器视图”,嵌入你的其他视图控制器。 然后你将能够在容器视图中添加导航控制器(例如使用嵌入关系segue)

看到实现容器视图控制器

[[UIApplication sharedApplication].windows.lastObject addSubview:myView];

Swift版本的检查响应:

Swift 4:

let view = UIView()
view.frame = UIApplication.shared.keyWindow!.frame
UIApplication.shared.keyWindow!.addSubview(view)

Swift 3.1:

let view = UIView()
view.frame = UIApplication.sharedApplication().keyWindow!.frame
UIApplication.sharedApplication().keyWindow!.addSubview(view)

@Nicolas Bonnet回答的快速版本:

    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
}

不要忘记,窗口必须是一个强属性,因为最初的答案会导致立即释放窗口

[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];

enter image description here

注意,如果你想在全屏中添加视图,那么只能使用下面的代码

添加这些ui扩展

public 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
}
}
}

继续正常的子视图添加过程

现在用于添加的ui viewDidAppear

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)


self.makeViewAsFullScreen()
}
UIApplication.shared.keyWindow?.insertSubview(yourView, at: 1)

这个方法适用于xcode 9.4, iOS 11.4

@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
人力资源> < p > < 你可以用一个扩展来更好地做到这一点:

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()

在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!)

Objective - C

这是你的视图

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
你需要添加一个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)