Теперь в iOS 11, sizeThatFits
от метода не называют UINavigationBar
подклассы. Изменение кадра UINavigationBar
незначительные сбои причин и неправильно вставляют. Так, какие-либо идеи, как настроить navbar высоту теперь?
Это работает хорошо на регулярную панель навигации. Если Ваше использование LargeTitle, эта привычка работает хорошо, потому что titleView размер не будет фиксированной высотой 44 точек. Но для регулярного представления это должно быть, достаточны.
Как @frangulyan яблоко предложил добавить представление под navBar и скрыть тонкую строку (теневое изображение). Это - то, что я придумал ниже. Я добавил uiview к titleView navigationItem и затем добавил imageView в этом uiview. Я удалил тонкую строку (теневое изображение). uiview, который я добавил, тот же точный цвет как navBar. Я добавил uiLabel в том представлении и вот именно.
Вот 3-е изображение. Расширенное представление находится позади usernameLabel под navBar. Его серый и имеет тонкую нижнюю часть строки его. Просто привяжите свой collectionView или безотносительно нижней части тонкого separatorLine.
9 шагов объяснены выше каждой строки кода:
class ExtendedNavController: UIViewController {
fileprivate let extendedView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .white
return view
}()
fileprivate let separatorLine: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .gray
return view
}()
fileprivate let usernameLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 14)
label.text = "username goes here"
label.textAlignment = .center
label.lineBreakMode = .byTruncatingTail
label.numberOfLines = 1
return label
}()
fileprivate let myTitleView: UIView = {
let view = UIView()
view.backgroundColor = .white
return view
}()
fileprivate let profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.clipsToBounds = true
imageView.backgroundColor = .darkGray
return imageView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// 1. the navBar's titleView has a height of 44, set myTitleView height and width both to 44
myTitleView.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
// 2. set myTitleView to the nav bar's titleView
navigationItem.titleView = myTitleView
// 3. get rid of the thin line (shadow Image) underneath the navigationBar
navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
navigationController?.navigationBar.layoutIfNeeded()
// 4. set the navigationBar's tint color to the color you want
navigationController?.navigationBar.barTintColor = UIColor(red: 249.0/255.0, green: 249.0/255.0, blue: 249.0/255.0, alpha: 1.0)
// 5. set extendedView's background color to the same exact color as the navBar's background color
extendedView.backgroundColor = UIColor(red: 249.0/255.0, green: 249.0/255.0, blue: 249.0/255.0, alpha: 1.0)
// 6. set your imageView to get pinned inside the titleView
setProfileImageViewAnchorsInsideMyTitleView()
// 7. set the extendedView's anchors directly underneath the navigation bar
setExtendedViewAndSeparatorLineAnchors()
// 8. set the usernameLabel's anchors inside the extendedView
setNameLabelAnchorsInsideTheExtendedView()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
// 9. **Optional** If you want the shadow image to show on other view controllers when popping or pushing
navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
navigationController?.navigationBar.setValue(false, forKey: "hidesShadow")
navigationController?.navigationBar.layoutIfNeeded()
}
func setExtendedViewAndSeparatorLineAnchors() {
view.addSubview(extendedView)
view.addSubview(separatorLine)
extendedView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
extendedView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
extendedView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
extendedView.heightAnchor.constraint(equalToConstant: 29.5).isActive = true
separatorLine.topAnchor.constraint(equalTo: extendedView.bottomAnchor).isActive = true
separatorLine.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
separatorLine.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
separatorLine.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
}
func setProfileImageViewAnchorsInsideMyTitleView() {
myTitleView.addSubview(profileImageView)
profileImageView.topAnchor.constraint(equalTo: myTitleView.topAnchor).isActive = true
profileImageView.centerXAnchor.constraint(equalTo: myTitleView.centerXAnchor).isActive = true
profileImageView.widthAnchor.constraint(equalToConstant: 44).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 44).isActive = true
// round the profileImageView
profileImageView.layoutIfNeeded()
profileImageView.layer.cornerRadius = profileImageView.frame.width / 2
}
func setNameLabelAnchorsInsideTheExtendedView() {
extendedView.addSubview(usernameLabel)
usernameLabel.topAnchor.constraint(equalTo: extendedView.topAnchor).isActive = true
usernameLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
usernameLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}
}