0

I have added navigation bar into application window but navigation bar collides with status bar. (I need to do it with application window).

Code I’ve tried is:

UIWindow * firstWindow = [UIApplication sharedApplication].windows[0];

UINavigationBar * navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, firstWindow.frame.size.width, 64)];

/*
// I tried these also
UINavigationBar * navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, firstWindow.frame.size.width, 84)];

UINavigationBar * navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 20, firstWindow.frame.size.width, 64)];
*/

[firstWindow addSubview:navBar];

Here are results:

enter image description here

enter image description here

I looked around these and tried all answers related to default navigation bar but nothing works:

What is the height of Navigation Bar in iOS 7?

iOS 10 custom navigation bar height

iOS 7 status and navigation bar different height in storyboard than in app

UINavigationBar/Status Bar issue in IOS7

When hiding the statusbar my navigation bar moves up in iOS7

iOS 7 Status Bar Collides With NavigationBar using ViewController

Krunal
  • 77,632
  • 48
  • 245
  • 261
  • Why you need add `UINavigationBar` in your main window? – Reinier Melian Sep 15 '17 at 12:10
  • I need to perform few app security related operations (authentication) on top of all views and screens and windows to prevent user access. Few codes in my app are already using top (root) view controller and its window for other operations. – Krunal Sep 15 '17 at 12:31
  • You need your navigation bar just like in your first image?, I mean with status bar background color blue? – Reinier Melian Sep 15 '17 at 12:34
  • what happens with 84 heigth? – Reinier Melian Sep 15 '17 at 12:55
  • It does not change to 84. it remains 44.. – Krunal Sep 15 '17 at 12:56
  • not sure but I think you need a custom navigation bar to do this, or at least using a view with your needed color and size of 84 and as subView your navigationBar – Reinier Melian Sep 15 '17 at 13:00
  • I tried to add subview as background of status bar in second image and it worked by but screen on which I'm implementing this, is accessible using globally shared instance. When I use this screen in between other view controllers, It shows custom backtround of status bar below default navigation bar. – Krunal Sep 15 '17 at 13:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/154537/discussion-between-reinier-melian-and-krunal). – Reinier Melian Sep 15 '17 at 13:05
  • Unless you specify a different origin, whatever gets added to the Window (which will have a bounds and frame equal to the entire handset's screen) will go to (0, 0), thus intersecting whatever else is at that origin. Status bars have a height of 20 points and navigation bars have a height of 44 points, typically. Changing the bounds/frame of a subview - after it's been added to its parent - has different ramifications then setting those properties ahead of time (because you are now working within the coordinate space of the parent). – BonanzaDriver Jan 25 '18 at 13:54

3 Answers3

2

Use additionalSafeAreaInsets for NavigationController,

self.navigationController.additionalSafeAreaInsets = UIEdgeInsetsMake(20, 0, 0, 0);
SergioPerm
  • 61
  • 3
1

This is how you would do it in iOS 11 using the safe area insets. You need a view controller under the hood so you can at least get notified when the safe area insets are updated. This code is from the single app template in Xcode 9. You can see the frame update between portrait and landscape mode as the safe areas are updated.

import UIKit

class ViewController: UIViewController {
    private var window: UIWindow!
    private var navbar: UINavigationBar!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.window = UIApplication.shared.windows[0]
        self.navbar = UINavigationBar(frame: CGRect(x: 0, y: self.view.safeAreaInsets.top, width: window.frame.size.width, height: 64))
        self.navbar.barTintColor = .red
        window.backgroundColor = .gray
        window.addSubview(navbar)
        self.view.backgroundColor = .clear
    }

    override func viewSafeAreaInsetsDidChange() {
        let navBarHeight: CGFloat = 64
        self.navbar.frame = CGRect(x: 0, y: self.view.safeAreaInsets.top, width: self.window.bounds.width, height: navBarHeight)
    }
}

Here is an image from the simulator:

enter image description here

If you need to support iOS 10 and below then you need to also use the topLayoutGuide which was deprecated. The length property will give you similar information as the safe layout guides.

I feel compelled to add though that finding a way to use the navigation controller would be much easier and safer to use especially as you start supporting multiple versions of iOS and Apple upgrades UIKit.

JamWils
  • 785
  • 7
  • 17
1

Try this

 CGFloat height =  [UIApplication sharedApplication].statusBarFrame.size.height;

 UIWindow * firstWindow = [UIApplication sharedApplication].windows[0];

 UINavigationBar * navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, height, firstWindow.frame.size.width, 64)];

 [firstWindow addSubview:navBar];
Atmaram
  • 494
  • 4
  • 14