-
Notifications
You must be signed in to change notification settings - Fork 439
Open
Description
Since this commit, which was introduced in ver 4.0.0, viewWillDisappear is being called in unexpected situations.
Here is how to reproduce it:
- Place PagingViewController and a UILabel in ViewController using a UIStackView.
- Transition from FirstViewController in PagingViewController to SecondViewController using pushViewController.
- Go back and change the layout in ViewController (e.g., hiding the UILabel).
At this point, didLayoutSubviews is initialized in PagingViewController.viewDidDisappear, but since viewDidLayoutSubviews is not called during the screen transition, didLayoutSubviews remains in the initialized state. This causes viewWillDisappear to be called unexpectedly when layout changes occur.
Transitioning from the ViewController in PagingViewController and returning to it is a common pattern in many use cases, and it is essential to address this issue because screen layout changes are often assumed in such cases.
Please find the code snippet below that reproduces the issue:
import UIKit
import Parchment
class ViewController: UIViewController, FirstViewControllerDelegate {
private let label: UILabel = {
let label = UILabel()
label.text = "Layout Changed!"
label.textAlignment = .center
label.isHidden = true
return label
}()
private let stackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
stackView.spacing = 10
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
let firstViewController = FirstViewController()
firstViewController.delegate = self
let pagingViewController = PagingViewController(viewControllers: [
firstViewController
])
addChild(pagingViewController)
stackView.addArrangedSubview(pagingViewController.view)
pagingViewController.didMove(toParent: self)
pagingViewController.view.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(label)
view.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
stackView.topAnchor.constraint(equalTo: view.topAnchor)
])
}
func didTapChangeLayoutButton() {
label.isHidden.toggle()
view.setNeedsLayout()
}
}
protocol FirstViewControllerDelegate: AnyObject {
func didTapChangeLayoutButton()
}
class FirstViewController: UIViewController {
weak var delegate: FirstViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setupUI()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("FirstViewController.viewWillDisappear")
}
func setupUI() {
let firstButton = UIButton(type: .system)
firstButton.setTitle("Navigate", for: .normal)
firstButton.addTarget(self, action: #selector(navigateToSecondVC), for: .touchUpInside)
firstButton.frame = CGRect(x: 50, y: 100, width: 100, height: 50)
view.addSubview(firstButton)
let secondButton = UIButton(type: .system)
secondButton.setTitle("Change Layout", for: .normal)
secondButton.addTarget(self, action: #selector(changeLayout), for: .touchUpInside)
secondButton.frame = CGRect(x: 50, y: 200, width: 150, height: 50)
view.addSubview(secondButton)
}
@objc func navigateToSecondVC() {
let secondVC = SecondViewController()
navigationController?.pushViewController(secondVC, animated: true)
}
@objc func changeLayout() {
delegate?.didTapChangeLayoutButton()
}
}
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .blue
}
}Metadata
Metadata
Assignees
Labels
No labels