Mis à jour le 07 janvier 2018
Ce code est compatible avec XCode 9.2 et iOS 11.2.
J'ai eu le même problème. Voici ma solution. Je suppose que la taille de la hauteur est de 66.
Veuillez choisir ma réponse si elle vous aide.
Créer CINavgationBar.swift
import UIKit
@IBDesignable
class CINavigationBar: UINavigationBar {
//set NavigationBar's height
@IBInspectable var customHeight : CGFloat = 66
override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width, height: customHeight)
}
override func layoutSubviews() {
super.layoutSubviews()
print("It called")
self.tintColor = .black
self.backgroundColor = .red
for subview in self.subviews {
var stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("UIBarBackground") {
subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: customHeight)
subview.backgroundColor = .green
subview.sizeToFit()
}
stringFromClass = NSStringFromClass(subview.classForCoder)
//Can't set height of the UINavigationBarContentView
if stringFromClass.contains("UINavigationBarContentView") {
//Set Center Y
let centerY = (customHeight - subview.frame.height) / 2.0
subview.frame = CGRect(x: 0, y: centerY, width: self.frame.width, height: subview.frame.height)
subview.backgroundColor = .yellow
subview.sizeToFit()
}
}
}
}
Set Storyboard
Définir la classe de la barre de navigation personnalisée
Ajouter TestView + Définir SafeArea
ViewController.swift
import UIKit
class ViewController: UIViewController {
var navbar : UINavigationBar!
@IBOutlet weak var testView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
//update NavigationBar's frame
self.navigationController?.navigationBar.sizeToFit()
print("NavigationBar Frame : \(String(describing: self.navigationController!.navigationBar.frame))")
}
//Hide Statusbar
override var prefersStatusBarHidden: Bool {
return true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(false)
//Important!
if #available(iOS 11.0, *) {
//Default NavigationBar Height is 44. Custom NavigationBar Height is 66. So We should set additionalSafeAreaInsets to 66-44 = 22
self.additionalSafeAreaInsets.top = 22
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Create BackButton
var backButton: UIBarButtonItem!
let backImage = imageFromText("Back", font: UIFont.systemFont(ofSize: 16), maxWidth: 1000, color:UIColor.white)
backButton = UIBarButtonItem(image: backImage, style: UIBarButtonItemStyle.plain, target: self, action: #selector(SecondViewController.back(_:)))
self.navigationItem.leftBarButtonItem = backButton
self.navigationItem.leftBarButtonItem?.setBackgroundVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
}
override var prefersStatusBarHidden: Bool {
return true
}
@objc func back(_ sender: UITabBarItem){
self.navigationController?.popViewController(animated: true)
}
//Helper Function : Get String CGSize
func sizeOfAttributeString(_ str: NSAttributedString, maxWidth: CGFloat) -> CGSize {
let size = str.boundingRect(with: CGSize(width: maxWidth, height: 1000), options:(NSStringDrawingOptions.usesLineFragmentOrigin), context:nil).size
return size
}
//Helper Function : Convert String to UIImage
func imageFromText(_ text:NSString, font:UIFont, maxWidth:CGFloat, color:UIColor) -> UIImage
{
let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = NSLineBreakMode.byWordWrapping
paragraph.alignment = .center // potentially this can be an input param too, but i guess in most use cases we want center align
let attributedString = NSAttributedString(string: text as String, attributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.paragraphStyle:paragraph])
let size = sizeOfAttributeString(attributedString, maxWidth: maxWidth)
UIGraphicsBeginImageContextWithOptions(size, false , 0.0)
attributedString.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Le jaune est le barbackgroundView. L'opacité noire est BarContentView.
Et j'ai supprimé le backgroundColor de BarContentView.
C'est ça.
0 votes
La seule nouvelle API avec iOS 11 pour le moment avec UINavigationBar est :
open var prefersLargeTitles: Bool
et la valeur par défaut estfalse
.0 votes
Vérifiez les problèmes connus dans les notes de publication, car il s'agit d'une version bêta.
0 votes
J'ai le même problème, ma barre de navigation de taille personnalisée est très glitchy et mon ancien code ne fonctionne pas correctement.
1 votes
Ce problème persiste dans la version 2, même si les problèmes signalés dans la version 1 sont censés avoir été corrigés : sizeThatFits n'est pas invoqué par les sous-classes de UINavigationBar.
0 votes
J'ai refait le test aussi et le problème demeure :(.
0 votes
Non, ce problème n'est pas corrigé dans la version bêta 2.
0 votes
Testé avec la Beta 3, encore une fois pas de chance ....
1 votes
Dans la version bêta 3, sizeThatFits est invoqué mais ne semble rien faire avec une hauteur personnalisée. Ce problème a-t-il été mentionné dans les notes de mise à jour ?
1 votes
Pour moi, la barre de navigation est redimensionnée, mais la vue pense toujours qu'elle a la hauteur par défaut de 44 pixels. Donc ma vue est dessinée sous la barre de navigation personnalisée. p.s. Les bords étendus sont sur
none
.0 votes
Mise à jour : Toujours le même problème dans la Beta 4
1 votes
Oui, les barres de navigation de hauteur personnalisée sont toujours très problématiques dans la version bêta 4, malgré les notes de version qui l'indiquent : "Les barres de navigation devraient maintenant être correctes. (32076094)". Je vous suggère de remplir un rapport de bogue en double.
2 votes
UINavigationBar
n'utilise plus intentionnellementsizeThatFits
pour déterminer sa taille en raison du changement dynamique de la hauteur des barres de navigation dans iOS 11 avec les grands titres. Je ne sais donc pas ce qu'il est possible de faire pour obtenir une hauteur fixe dans iOS 11, à part construire votre propre barre de navigation qui n'est pas un titre de grande taille.UINavigationBar
. Je vous encourage à déposer une demande d'amélioration demandant une API pour influencer la hauteur de la barre de navigation pour iOS 11+.0 votes
@JeroenBakker Je constate le même comportement dans la bêta 4 - tout allait bien jusqu'à la bêta 4, la barre augmente de taille mais l'arrière-plan ne s'étend pas avec elle. J'ai enregistré un bug avec l'ID 33539673.
0 votes
Voici ma solution : stackoverflow.com/questions/46325181/