не заставляет navigationController?.pushViewController работать, но работает?

У меня есть не раскадровка, 100% закодированный UIViewController, UICollectionView и UICollectionViewCell - работает отлично.

вот код, о котором идет речь:

SceneDelegate не уверен, что это актуально, хотя.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)

        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let myController = MyViewController(collectionViewLayout: layout)
        window?.rootViewController = myController
        window?.makeKeyAndVisible()
    }
.
.

ViewController очень простой и понятный...

class MyViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
    let data = loadOnboardingData()
.
.
override func viewDidLoad() {
        super.viewDidLoad()

        collectionView?.backgroundColor = .white
        collectionView?.register(MyPageCell.self, forCellWithReuseIdentifier: "cellId")
        collectionView?.isPagingEnabled = true
        collectionView.showsHorizontalScrollIndicator = false
        collectionView?.tag = myPageControl.currentPage

        setupMyPageControl()

    }

ViewControllerExtention вот в чем проблема: метод pushViewController просто ничего не делает, но модальное представление работает как шарм, и я не понимаю, что не так и почему:

extension MyViewController: MyPageCellDelegate {
.
.
func didTabOnActionButton(title: String) {


        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        guard let homeViewController = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as? HomeViewController else {
            print("Coun't find controller")
            return
        }
        navigationController?.pushViewController(homeViewController, animated: true) <- NO EFFECT
        //present(homeViewController, animated: true, completion: nil) <- WORKS PERFECT!

    }

MyPageCell Я настроил Delegate по протоколу, и, кажется, это тоже нормально

protocol MyPageCellDelegate {
    func didTabOnActionButton(title: String)
}

class MyPageCell: UICollectionViewCell {

    var delegate: MyPageCellDelegate?

let myActionButton: UIButton = {
        let button = UIButton(type: .system)
        return button
    }()

myActionButton.addTarget(self, action: #selector(self.doAction), for: .touchUpInside)
.
.
@objc private func doAction(_ sende: Any) {
        delegate?.didTabEndOnboardingActionButton(title: "end Onboarding")
    }

Итак, любая идея, что не так с:

navigationController?.pushViewController(homeViewController, animated: true)

РЕДАКТИРОВАТЬ ------------------------------------------------- --------------------

Как указал @Michcio, здесь: window?.rootViewController = UINavigationController(rootViewController: myController) работает наполовину, и, насколько я понимаю, я встраиваю myController в UINavigationController, который добавляет панель навигации к текущему и следующему контроллерам.

Но это не то, что мне нужно!

Мне нужен чистый и простой для адаптации, т.е. MyViewController и HomeViewController должны быть одним целым с панелью вкладок и навигации.

В основном, начиная с нуля после адаптации.

Раньше я решал это в предыдущей версии, редактируя первый метод AppDelegate следующим образом (в этом примере я использовал раскадровки):

extension AppDelegate {

    func showOnboarding() {
        if let window = UIApplication.shared.keyWindow, let onboardingViewController = UIStoryboard(name: "Onboarding", bundle: nil).instantiateInitialViewController() as? OnboardingViewController {
            onboardingViewController.delegate = self
            window.rootViewController = onboardingViewController
        }
    }

    func hideOnboarding() {
        if let window = UIApplication.shared.keyWindow, let mainViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() {
            mainViewController.view.frame = window.bounds
            UIView.transition(with: window, duration: 0.5, options: .transitionCrossDissolve, animations: {
                window.rootViewController = mainViewController
            }, completion: nil)
        }
    }
}

а в самом делегате вот так:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let isFirstRun = true // logic to determine goes here
    if isFirstRun {
        showOnboarding()
    }
    return true
}

но я серьезно не понимаю новый SceneDelegate или просто не понимаю его

Был бы очень признателен, если бы кто-то мог вставить здесь какой-то код для повторного использования.


person Michael Kocurek    schedule 08.10.2019    source источник
comment
Хм, можете ли вы предоставить пример проекта с вашей проблемой, то есть на github? Будет легче понять, что здесь не так.   -  person Michcio    schedule 09.10.2019


Ответы (1)


Это не сработало, потому что вы установлены MyViewController как window.rootViewController. Просто измените строку в SceneDelegate на:

window?.rootViewController = UINavigationController(rootViewController: myController)

person Michcio    schedule 08.10.2019
comment
но когда я это сделаю, как я могу убедиться, что первый ViewController, который появляется при запуске приложения, будет MyViewController? - person Michael Kocurek; 09.10.2019
comment
Вы устанавливаете его как rootViewController :) - person Michcio; 09.10.2019
comment
см. раздел РЕДАКТИРОВАТЬ моего сообщения выше .... это все еще неясно, и я ужасно извиняюсь за непонимание этого нового SceneDelegate - person Michael Kocurek; 09.10.2019