1

Hello I updated to new Xcode 9 and started using safeAreaLayout guide to support iphone X. From xib, I just used safeAreaLayout guide and adjusted by top and bottom constraints to safeArea.

Here is what I got

iphone X (iOS 11)

iphone 6 (iOS 11)

As you can see my custom navigation bar is down 20pxls

iphone 6 (iOS 9 and 10)

Here you can see how the navigation bar starts from 0 and status bar is merged.

Actually,

1) I want the green color to filled by notch. 2) Status Bar should not show in white color but green color as in 3 image.

I have searched many solutions. But none is working. So I need help.

Regards Ranjit

brandonscript
  • 68,675
  • 32
  • 163
  • 220
Ranjit
  • 4,576
  • 11
  • 62
  • 121
  • Without seeing any code, it's hard to know how you've laid out your app, but it looks like you're not using a UINavigationController. If you do, the status bar color and the screen to the left and right of the notch will change accordingly. – brandonscript Nov 16 '17 at 18:45
  • share some more details.., like is your navigation controller is inside any container or it is the root controller of window or some other setup? – Er. Khatri Nov 16 '17 at 18:50
  • I am using navigationController, but my default navBar is hidden and I am using customView – Ranjit Nov 16 '17 at 18:57
  • @brandonscript, the green navigationBar is the customView. But I am pushing this using UINavigationController – Ranjit Nov 16 '17 at 19:10

3 Answers3

0

Your custom bar's view is being laid out like:

[nav.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor];

Anything that is constrained to the view.safeAreaLayoutGuide.topAnchor will be below the statusBar + navigationBar because that is the safe area.. If it is constrained to safeAreaLayoutGuide.bottomAnchor, then it will be above all tabBars or bottom bars so that iPhone X users can swipe up without touching your view..

However, anything constrained to view.topAnchor will be constrained to the top of the view (IE: The screen)..

So constrain your custom view to the top of your controller's view. Then in viewDidLayoutSubviews, add safeAreaInsets.top to the height. This will allow your view to be touching the top of the screen, but tall/large enough to extend below the navBar. Your will need to adjust the contents of your view to layout further down by the same inset top.

//
//  ViewController.swift
//  SONav
//
//  Created by Brandon Anthony on 2017-11-17.
//  Copyright © 2017 SO. All rights reserved.
//

import UIKit

class CustomNav : UINavigationBar {

    var desiredHeight: CGFloat = 88.0

    override init(frame: CGRect) {
        super.init(frame: frame)

        desiredHeight = frame.size.height
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var size = super.sizeThatFits(size)
        size.height = desiredHeight
        return size
    }

    override var frame: CGRect {
        get {
            return super.frame
        }

        set {
            var frm = newValue
            frm.size.height = desiredHeight
            super.frame = frm
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        for subview in self.subviews {
            if NSStringFromClass(type(of: subview)).contains("Background") {
                subview.frame.size.height = 0
            }
            else if NSStringFromClass(type(of: subview)).contains("ContentView") {
                subview.frame.origin.y = 0
            }
        }
    }
}

class CustomNavigationController : UINavigationController {
    override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
        super.willTransition(to: newCollection, with: coordinator)
        self.setNeedsStatusBarAppearanceUpdate()
    }
}

class ViewController: UIViewController {
    var customNav: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        //Navigation Bar Setup
        self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
        self.navigationController?.navigationBar.isTranslucent = true
        self.navigationController?.view.backgroundColor = UIColor.clear
        self.navigationController?.navigationBar.backgroundColor = UIColor.clear
        self.navigationController?.navigationBar.shadowImage = nil

        self.view.backgroundColor = UIColor.white
        self.customNav = CustomNav(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 100))
        self.customNav.backgroundColor = UIColor.blue
        self.view.addSubview(self.customNav!)

        NSLayoutConstraint.activate([
            self.customNav.leftAnchor.constraint(equalTo: self.view.leftAnchor),
            self.customNav.rightAnchor.constraint(equalTo: self.view.rightAnchor),
            self.customNav.topAnchor.constraint(equalTo: self.view.topAnchor),
            self.customNav.heightAnchor.constraint(equalToConstant: 100.0)
        ])

        self.customNav.translatesAutoresizingMaskIntoConstraints = false
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
Brandon
  • 22,723
  • 11
  • 93
  • 186
0

The status bar's background is showing the color of the view below it. To change the "color of the status bar", you need to place a view behind it and give that view a background color.

To solve your problem, the easiest solution is to create a separate view that is always the height of the status bar and has the same background color as your custom navigation view.

To do this, pin the new view's top to the top of the superview, and pin its bottom to the top of your custom navigation view.

This solution is simpler than adding the height of the top safe area inset to your custom navigation view because it avoids adjusting the custom view's layout to account for this extra variable height.

nathangitter
  • 9,607
  • 3
  • 33
  • 42
0

1- You should select superview for your view's top constraint (if not)

enter image description here

2- Double click on this constraint. If you see Margin

enter image description here

3- Uncheck relative to margin

enter image description here

4- Set constraint value to 0 again

missionMan
  • 873
  • 8
  • 21
  • I am using safeAreaLayout guideLines – Ranjit Nov 17 '17 at 03:00
  • Is it normal for the top side to remain empty in this case? You know safe area does not cover full screen. https://developer.apple.com/ios/human-interface-guidelines/visual-design/adaptivity-and-layout/ – missionMan Nov 17 '17 at 06:32