Цвет строки состояния не меняется на iPhone X слева и справа от выемки

Привет, я обновился до нового Xcode 9 и начал использовать руководство safeAreaLayout для поддержки iphone X. Из xib я просто использовал руководство safeAreaLayout и скорректировал верхние и нижние ограничения для safeArea.

Вот что я получил

айфон Х (iOS 11)

айфон 6 (iOS 11)

Как видите, моя пользовательская панель навигации опущена на 20 пикселей.

айфон 6 (iOS 9 и 10)

Здесь вы можете увидеть, как панель навигации начинается с 0, а строка состояния объединяется.

На самом деле,

1) Я хочу, чтобы зеленый цвет был заполнен надрезом. 2) Строка состояния должна отображаться не белым, а зеленым цветом, как на изображении 3.

Я искал много решений. Но ни один не работает. Так что мне нужна помощь.

С уважением Ранджит


person Ranjit    schedule 16.11.2017    source источник
comment
Не видя никакого кода, трудно понять, как вы разложили свое приложение, но похоже, что вы не используете UINavigationController. Если вы это сделаете, цвет строки состояния и экрана слева и справа от выемки изменится соответственно.   -  person brandonscript    schedule 16.11.2017
comment
поделитесь некоторыми подробностями.. например, ваш навигационный контроллер находится внутри какого-либо контейнера или это корневой контроллер окна или какая-то другая настройка?   -  person Er. Khatri    schedule 16.11.2017
comment
Я использую navigationController, но мой navBar по умолчанию скрыт, и я использую customView   -  person Ranjit    schedule 16.11.2017
comment
@brandonscript, зеленая панель навигации — это customView. Но я нажимаю это с помощью UINavigationController   -  person Ranjit    schedule 16.11.2017


Ответы (3)


Фон строки состояния показывает цвет представления под ним. Чтобы изменить «цвет строки состояния», вам нужно поместить вид за ним и присвоить этому виду цвет фона.

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

Для этого прикрепите верхнюю часть нового представления к верхней части суперпредставления, а нижнюю часть — к верхней части пользовательского представления навигации.

Это решение проще, чем добавление высоты вставки верхней безопасной области в пользовательское представление навигации, поскольку оно позволяет избежать настройки макета пользовательского представления для учета этой дополнительной переменной высоты.

person nathangitter    schedule 16.11.2017
comment
должен ли этот новый вид быть внутри safeArea или снаружи? - person Ranjit; 17.11.2017
comment
@Ranjit Новый вид будет находиться за пределами безопасной области (над ней), охватывая область, содержащую строку состояния. - person nathangitter; 17.11.2017
comment
Дай мне попробовать. Но чем у меня так много просмотров. Я должен повторить это во всех xibs. - person Ranjit; 17.11.2017

1- Вы должны выбрать superview для верхнего ограничения вашего представления (если нет)

введите здесь описание изображения

2- Дважды щелкните это ограничение. Если вы видите Margin

введите здесь описание изображения

3- Снимите флажок относительно поля

введите здесь описание изображения

4- Установите значение ограничения снова на 0

person missionMan    schedule 16.11.2017
comment
Я использую направляющие линии safeAreaLayout - person Ranjit; 17.11.2017
comment
Нормально ли, что в этом случае верхняя сторона остается пустой? Вы знаете, что безопасная зона не занимает весь экран. developer.apple.com/ios/human -интерфейс-рекомендации/ - person missionMan; 17.11.2017

Ваш пользовательский вид панели выкладывается следующим образом:

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

Все, что ограничено view.safeAreaLayoutGuide.topAnchor, будет находиться ниже statusBar + navigationBar, потому что это безопасная область. можно провести вверх, не касаясь экрана..

Однако все, что ограничено view.topAnchor, будет ограничено верхней частью представления (IE: экран).

Поэтому ограничьте свой пользовательский вид верхней частью представления вашего контроллера. Затем в viewDidLayoutSubviews добавьте safeAreaInsets.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.
    }
}
person Brandon    schedule 16.11.2017
comment
можете ли вы поделиться примером кода, чтобы он помог мне лучше понять - person Ranjit; 17.11.2017