Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

viewWillDispear is called in unexpected situations #728

Open
renshi-asada opened this issue Aug 20, 2024 · 0 comments
Open

viewWillDispear is called in unexpected situations #728

renshi-asada opened this issue Aug 20, 2024 · 0 comments

Comments

@renshi-asada
Copy link

Since this commit, which was introduced in ver 4.0.0, viewWillDisappear is being called in unexpected situations.

Here is how to reproduce it:

  1. Place PagingViewController and a UILabel in ViewController using a UIStackView.
  2. Transition from FirstViewController in PagingViewController to SecondViewController using pushViewController.
  3. 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()
        let secondViewController = SecondViewController()
        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
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant