Present UIViewController using sheetPresentationController inside UINavigationController

42 Views Asked by At

I have a navigation controller, and it has a root view controller. I want to present a sheet using sheetPresentationController. Then I want to push another view controller to the navigation controller. But the sheet stays on top of the screen. When I debug, I see that the sheet is presented by navigation controller itself, instead of the root view controller. What I want is to keep the sheet inside the root view controller's frame.

(I tried to do this without a child view controller, neither it works.)

This is my code and the gif below.

class ViewController: UIViewController {

    let sheet = UIViewController()
    let push = UIViewController()
    let child = UIViewController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        addChild(child)
        view.addSubview(child.view)
        child.didMove(toParent: self)
        
        let btnPush = UIButton()
        btnPush.setTitle("PUSH", for: .normal)
        btnPush.setTitleColor(.black, for: .normal)
        btnPush.addTarget(self, action: #selector(btnPushPressed), for: .touchUpInside)
        
        child.view.addSubview(btnPush)
        
        child.view.translatesAutoresizingMaskIntoConstraints = false
        btnPush.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            child.view.topAnchor.constraint(equalTo: view.topAnchor),
            child.view.leftAnchor.constraint(equalTo: view.leftAnchor),
            child.view.rightAnchor.constraint(equalTo: view.rightAnchor),
            child.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            btnPush.centerXAnchor.constraint(equalTo: child.view.centerXAnchor),
            btnPush.centerYAnchor.constraint(equalTo: child.view.centerYAnchor, constant: -200),
        ])

        sheet.sheetPresentationController?.detents = [.medium()]
        sheet.sheetPresentationController?.largestUndimmedDetentIdentifier = .medium
        
        sheet.view.backgroundColor = .red
        push.view.backgroundColor = .white
        
        child.present(sheet, animated: true)
    }

    @objc
    func btnPushPressed() {
        navigationController?.pushViewController(push, animated: true)
    }
}

enter image description here

1

There are 1 best solutions below

3
GGShin On

You can add logic to dismiss the presented sheet at viewWillDisappear method.

override func viewWillDisappear(_ animated: Bool) {      
   super.viewWillDisappear(animated)
   
   // Dissmiss here.
   sheet.dismiss(animated: true)
}

I am quite not so sure about

When I debug, I see that the sheet is presented by navigation controller itself, instead of the root view controller..

I think it should be presented by child view controller, that is where you present the sheet. I hope someone might have an idea for this issue!