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

时间:2014-02-18 10:11:33

标签: ios uiviewcontroller uinavigationbar popupwindow

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

  • 全屏黑色背景,0.5 alpha以查看下方的其他UIViewController
  • 中间有一个UIView窗口,上面有一些信息,(如果你想了解所有内容,可以使用日历)。

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

我试图将其作为模态呈现,但下面的UIViewController消失了,我的透明效果会失效。

任何想法都这样做,我相信这很简单......

谢谢!

18 个答案:

答案 0 :(得分:176)

您可以直接将视图添加到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)

答案 1 :(得分:123)

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

答案 2 :(得分:94)

这是一个适合我的简单优雅的解决方案。您可以将导航栏的z位置设置为视图下方:

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

请记住在完成后将其设置为0.

答案 3 :(得分:56)

检查响应的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)

答案 4 :(得分:20)

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

[self.navigationController.navigationBar addSubview: overlayView)]

您也可以在窗口上添加它:

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

希望这会有所帮助.. :)

答案 5 :(得分:17)

Dalef在swift中的出色解决方案:

self.navigationController?.view.addSubview(view)

答案 6 :(得分:8)

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

不要忘记窗口必须是强大的属性,因为原始答案会导致窗口立即释放

答案 7 :(得分:6)

有多种方法可以做到:

1-在UIView上添加UIWindow,而不是在UIViewController上添加 [[(AppDelegate *)[UIApplication sharedApplication].delegate window] addSubview:view]; 。通过这种方式,它将成为一切。

{{1}}

2-使用自定义转换,让你的UIViewController在后面显示0.5 alpha

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

答案 8 :(得分:5)

我建议你创建一个新的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;
希望这会有所帮助!

答案 9 :(得分: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()

答案 10 :(得分:4)

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

答案 11 :(得分:2)

请注意,如果您想在全屏幕中添加视图,请仅使用以下代码

添加 UIViewController的扩展程序

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

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

现在用于添加 UIViewController的viewDidAppear

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

     self.makeViewAsFullScreen()
}

答案 12 :(得分:2)

        <StackLayout row="1" orientation="horizontal" backgroundColor="#eae8e8" class="foot">
            <Label width="25%" textAlignment="left" [nsRouterLink]="['/photos']">
                <FormattedString>
                    <Span text="Photos"></Span>
                </FormattedString>
            </Label>
   <Label width="25%" textAlignment="left" [nsRouterLink]="['/albums']">
                <FormattedString>
                    <Span text="Albums"></Span>
                </FormattedString>
            </Label>
         </StackLayout>

此方法适用于xcode 9.4,iOS 11.4

答案 13 :(得分:1)

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

请参阅Implementing a Container View Controller

答案 14 :(得分: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];

这只能在纵向或横向模式下工作。

答案 15 :(得分:0)

[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

答案 16 :(得分:0)

如果要在导航栏上方添加UIView并在另一个视图下方,该怎么做?

示例:Apple的语音备忘录应用程序 Apple's Voice Memos Screenshot

我已经尝试了以上所有代码建议:

transparentView.frame = (navigationController?.view.frame)!
navigationController?.view.addSubview(transparentView)

transparentView.frame = (navigationController?.view.frame)!
UIApplication.shared.keyWindow?.addSubview(transparentView)

但是我还有另一个要求。我使用这种方式在视图中定义元素:

topPartialView.translatesAutoresizingMaskIntoConstraints = false
topPartialView.heightAnchor.constraint(equalToConstant: recViewHeight).isActive = true
topPartialView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
topPartialView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
topPartialView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: recViewHeight-100).isActive = true

我在Navigation Controller的主视图上方添加了2个视图,但是要用ANCHORS定义该视图...不可能!

答案 17 :(得分:0)

您需要使用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)