Tout d'abord, il n'est actuellement pas possible de faire UINavigationController
se comportent de cette manière. Cependant, vous pouvez envelopper votre UINavigationController
dans un contrôleur de vue de conteneur.
Cela vous donnera le contrôle de la gestion de l'espace supérieur à partir duquel l UINavigationController
la mise en page de la vue commence. À l'intérieur de cette classe de conteneur, vous pouvez la gérer comme suit
class ContainerViewController: UIViewController {
private lazy var statusBarBackgroundView: UIView = {
let view = UIView(frame: .zero)
view.backgroundColor = .clear
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var statusBarBackgroundViewHeightConstraint: NSLayoutConstraint = {
statusBarBackgroundView.heightAnchor.constraint(equalToConstant: 0)
}()
var statusBarHeight: CGFloat {
if #available(iOS 13.0, *) {
guard let statusBarMananger = self.view.window?.windowScene?.statusBarManager
else { return 0 }
return statusBarMananger.statusBarFrame.height
} else {
return UIApplication.shared.statusBarFrame.height
}
}
var statusBarHidden: Bool = false {
didSet {
self.statusBarBackgroundViewHeightConstraint.constant = self.statusBarHidden ? self.lastKnownStatusBarHeight : 0
self.view.layoutIfNeeded()
}
}
private var lastKnownStatusBarHeight: CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
let topView = self.statusBarBackgroundView
self.view.addSubview(topView)
NSLayoutConstraint.activate([
topView.topAnchor.constraint(equalTo: self.view.topAnchor),
topView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
statusBarBackgroundViewHeightConstraint,
topView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
])
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let height = self.statusBarHeight
if height > 0 {
self.lastKnownStatusBarHeight = height
}
}
func setUpNavigationController(_ navCtrl: UINavigationController) {
self.addChild(navCtrl)
navCtrl.didMove(toParent: self)
self.view.addSubview(navCtrl.view)
navCtrl.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
navCtrl.view.topAnchor.constraint(equalTo: statusBarBackgroundView.bottomAnchor),
navCtrl.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
navCtrl.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
navCtrl.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
])
self.view.layoutIfNeeded()
}
}
Maintenant, à partir de votre site d'appel, vous pouvez faire ce qui suit -.
class ViewController: UIViewController {
var statusBarHidden: Bool = false {
didSet {
UIView.animate(withDuration: Constants.config_shortAnimTime) { () -> Void in
/// Forward the call to ContainerViewController to act on this update
(self.navigationController?.parent as? ContainerViewController)?.statusBarHidden = self.statusBarHidden
/// Keep doing whatever you are doing now
self.setNeedsStatusBarAppearanceUpdate()
}
}
}
}