0

I'm using UIKit in Swift.

I have a button that opens a sheet:

@objc func myButtonTapped(_ sender: UIButton) {
    if let myTitle = sender.title(for: .normal) {
        let sheet = self.storyboard?.instantiateViewController(withIdentifier: "myConfigView") as! myConfigViewController
        sheet.title = myTitle
        self.present(sheet, animated: true)
    }
}

There is a label on the sheet that, if I press it, I want a new view to open. But it's not working. The sheet code:


class myConfigViewController: BaseViewController, UISheetPresentationControllerDelegate {
    
    override var sheetPresentationController: UISheetPresentationController{
        presentationController as! UISheetPresentationController
    }

    
    @IBOutlet weak var TitleUILabel: UILabel!
    @IBOutlet weak var openUILabel: UILabel!
    
    var title:String = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()

        sheetPresentationController.delegate = self
        sheetPresentationController.selectedDetentIdentifier = .medium
        sheetPresentationController.prefersGrabberVisible = false
        sheetPresentationController.detents = [.medium()]
        
        TitleUILabel.text = title
        
        let tapGesture1 = UITapGestureRecognizer(target: self, action: #selector(openNewViewLabelTapped))
        openUILabel.isUserInteractionEnabled = true
        openUILabel.addGestureRecognizer(tapGesture1)     
        
    }
    
    
    @objc func openNewViewLabelTapped() {
        print("Open the new View")
        self.dismiss(animated: false){
            let destViewController = self.storyboard!.instantiateViewController(withIdentifier: "isNewView") as! isNewViewController
            self.navigationController?.pushViewController(destViewController, animated: true)
        } 
    }
}

It doesn't show any errors. Do nothing.

What is the solution?

THANKS!

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
web216
  • 75
  • 4
  • Not sure but check this may help https://stackoverflow.com/questions/68198904/uisheetpresentationcontrollerdelegate-method-not-called – Prashant Tukadiya Aug 22 '23 at 12:43
  • *"I want a new view to open"* ... what does that mean? Do you want to *dismiss* the presented `myConfigViewController` and then push to `isNewViewController`? Or are you trying to push to `isNewViewController` inside the presented `myConfigViewController`? – DonMag Aug 22 '23 at 13:10
  • @DonMag I want dismiss the presented myConfigViewController and then push to isNewViewController. Thanks. – web216 Aug 22 '23 at 13:31

1 Answers1

1

When you present a view controller from a controller that is in a navigation controller, the presented controller is NOT in the navigation stack.

So, it has no .navigationController property, and self.navigationController?.pushViewController(...) won't do anything.

There are various ways to do what you want -- here is one approach:

  • add a closure to your myConfigViewController class to tell the presenting controller to "dismiss and move on"
  • set that closure before you present myConfigViewController
  • in func openNewViewLabelTapped() call that closure
  • instantiate and push isNewViewController from that closure

So, add this property to myConfigViewController:

public var dismissAndPush: (() -> ())?

change your openNewViewLabelTapped() func to:

@objc func openNewViewLabelTapped() {
    print("Open the new View")
    if dismissAndPush != nil {
        dismissAndPush?()
    } else {
        self.dismiss(animated: false)
    }
}

then, in your controller that presents myConfigViewController:

@objc func myButtonTapped(_ sender: UIButton) {
    if let myTitle = sender.title(for: .normal) {
        if let sheet = self.storyboard?.instantiateViewController(withIdentifier: "myConfigView") as? myConfigViewController {

            sheet.title = myTitle
            
            // set the closure
            sheet.dismissAndPush = { [weak self] in
                guard let self = self else { return }
                self.dismiss(animated: false)
                if let destViewController = self.storyboard?.instantiateViewController(withIdentifier: "isNewView") as? isNewViewController {
                    self.navigationController?.pushViewController(destViewController, animated: true)
                }
            }
            
            self.present(sheet, animated: true)

        }
    }
}

Now, openNewViewLabelTapped() will call the closure ... and that is where dismiss and push will take place.


As a side note -- class names should start with Uppercase letters, var / property / func names should start with lowercase letters.

DonMag
  • 69,424
  • 5
  • 50
  • 86