Reputation: 239
First view controller has navigation bar hidden. Second has visible nav bar with large title. Transition forward is fine. Scroll view behaves as intended - navigation bar stretches while pulling down, and shrinks when pulling up. However when I use swipe back gesture and cancel it, scroll view "disconnects" from navigation bar and now it doesn't shrink or stretch.
Xcode 11.3, iOS 13.3
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .orange
button.addTarget(self, action: #selector(tap), for: .touchUpInside)
setupNavigationController()
}
func setupNavigationController() {
if #available(iOS 13.0, *) {
let coloredAppearance = UINavigationBarAppearance()
coloredAppearance.configureWithOpaqueBackground()
coloredAppearance.backgroundColor = .white
coloredAppearance.titleTextAttributes = [.foregroundColor: UIColor.black]
coloredAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 26)]
let coloredAppearance2 = UINavigationBarAppearance(barAppearance: coloredAppearance)
coloredAppearance2.shadowColor = nil
navigationController?.navigationBar.standardAppearance = coloredAppearance
navigationController?.navigationBar.scrollEdgeAppearance = coloredAppearance2
}
navigationController?.navigationBar.prefersLargeTitles = true
}
@objc func tap() {
navigationController?.pushViewController(DetailsViewController(), animated: true)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: true)
}
}
Second view controller
class DetailsViewController: UIViewController, UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
title = "Details"
view.backgroundColor = .systemPink
let tableView = UITableView(frame: .zero, style: .grouped)
tableView.dataSource = self
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(false, animated: true)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = {
let identifier = "cell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: identifier) else {
return UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: identifier)
}
return cell
}()
cell.textLabel?.text = "Row \(indexPath.row)"
return cell
}
}
Upvotes: 3
Views: 431
Reputation: 535306
It's a clear bug. Here's a workaround. To your table view controller, add this code:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.view.setNeedsLayout()
}
Upvotes: 2