Слишком низкий UINavigationBar при использовании UIScreen.main.bounds в качестве фрейма UIWindow

Я создаю приложение для iOS, цель развертывания 12.1, swift 4.2. Приложение использует контейнерные представления и имеет панель навигации в верхней части основных экранов, желательно прямо под строкой состояния. В раскадровке экрана запуска я ограничил Navigation Bar.top значением Safe.Area.Top. Это прекрасно работает. Но после того, как я установил containerViewController как rootViewController в AppDelegate, панель навигации, как я ограничил ее в Main.storyboard (Navigation Bar.top в Safe.Area.Top), появляется намного ниже, чем она должна быть.

Единственный способ, которым я могу заставить панель навигации отображаться прямо под строкой состояния, — это создать собственный фрейм для моего окна в AppDelegate с отрицательным значением y — и это определенно НЕ то решение, с которым мне удобно.

Кажется, это создает слишком низкое значение y:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        window = UIWindow(frame: UIScreen.main.bounds)
        let containerViewController = ContainerViewController()
        window!.rootViewController = containerViewController
        window!.makeKeyAndVisible()
        return true
    }

И это вопиющий хак, который приближает панель навигации к тому месту, где она должна быть:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        //window = UIWindow(frame: UIScreen.main.bounds)
        let hackedFrame = CGRect(x: 0, y: -44, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        window = UIWindow(frame: hackedFrame)
        let containerViewController = ContainerViewController()
        window!.rootViewController = containerViewController
        window!.makeKeyAndVisible()
        //window!.windowLevel = UIWindow.Level.statusBar
        return true
    }

Снимки экрана:

экран запуска, правильная панель навигации

сообщение на главном экране didFinishLaunchingWithOptions, панель навигации слишком низкая

Я, вероятно, упускаю что-то действительно очевидное здесь, но я был бы признателен за любую помощь, которую может оказать любой.

Спасибо.


person user2271541    schedule 12.04.2019    source источник
comment
Если мы создаем окно и его rootViewController с помощью кода внутри делегата приложения, main.storyboard станет бесполезным. Приложение покажет только те изменения, которые вы сделаете внутри класса viewcontroller.   -  person Akash Bhardwaj    schedule 13.04.2019
comment
Пожалуйста, поделитесь также кодом вашего класса ContainerViewController, это поможет нам дать лучший ответ.   -  person Akash Bhardwaj    schedule 13.04.2019
comment
Раскадровка действительно становится бесполезной? Как вы видите на снимках экрана, которые я разместил, панель навигации и кнопка, которые я создал, все еще существуют. Кнопка работает идеально. Это просто на ~ 44 балла меньше.   -  person user2271541    schedule 15.04.2019
comment
По моему опыту, это становится бесполезным, если и до тех пор, пока вы не вызовете раскадровку где-то в своем коде. Учитывая ваш сценарий, я думаю, вы также добавили панель навигации где-то в свой код класса ContainerViewController.   -  person Akash Bhardwaj    schedule 15.04.2019
comment
Я вижу, что ты говоришь. На самом деле я понял основную причину проблемы. Я основываю свой проект на чьем-то уже существующем коде (всегда опасном). Они ориентировались на более раннюю версию ОС и использовали руководства по макету, которые сейчас устарели. Короче говоря, я обрабатываю пользовательский интерфейс в основном программно и не имею проблем. Спасибо за вашу помощь, в любом случае!   -  person user2271541    schedule 16.04.2019


Ответы (2)


В iOS 11 Apple представила большие заголовки на панели навигации, что означает, что ее можно растянуть, если потянуть. Вы должны попробовать установить

navigationItem.largeTitleDisplayMode = .never

В вашем представленииDidLoad и установите для PrefersLargeTitles вашей панели навигации значение false

if #available(iOS 11.0, *) {
   navigationItem.largeTitleDisplayMode = .always
   navigationController?.navigationBar.prefersLargeTitles = true
} 
person Gabriel Henrique Paul    schedule 12.04.2019
comment
Спасибо за ответ, но это не решило проблему. - person user2271541; 13.04.2019
comment
Вы пытались сделать верхнее ограничение navBar относительно его супервизора, а не безопасной области? - person Gabriel Henrique Paul; 13.04.2019
comment
Да. Пробовал и безопасную зону, и супервизор. Ни то, ни другое не сработало. - person user2271541; 13.04.2019

попробуйте добавить панель навигации в ViewController вместо AppDelegate следующим образом:

var screenWidth : CGFloat!
var screenHeight : CGFloat!
let screenSize: CGRect = UIScreen.main.bounds

внутри ViewDidLoad:

screenWidth = screenSize.width
screenHeight = screenSize.height

navigationBar = UINavigationBar(frame: CGRect(x: 0, y: 20, width: screenWidth, height: screenWidth / 3))

для добавления заголовка и кнопки:

view.addSubview(navigationBar)
    let navItem = UINavigationItem(title: "MainController")
    let doneItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.cancel, target: nil, action: #selector(DismissViewController))
    navItem.leftBarButtonItem = doneItem
    UINavigationBar.appearance().barTintColor = .white
    navigationBar.setItems([navItem], animated: false)
person Arash Afsharpour    schedule 12.04.2019
comment
Да, похоже, это помогло. Признаюсь, я новичок в iOS и xcode, но, чувак, мне ужасно не повезло с конструктором интерфейсов. Программные решения проблем с пользовательским интерфейсом обычно работают лучше всего для меня. Спасибо. - person user2271541; 13.04.2019
comment
Я делаю то же самое с прошлой недели, теперь я делаю весь пользовательский интерфейс в коде, я удаляю Storyboard сразу после того, как начинаю новый проект, я рекомендую вам использовать библиотеку Snapkit для управления пользовательским интерфейсом, это действительно упрощает для вас - person Arash Afsharpour; 13.04.2019