Reputation: 105
I do have a non-Storyboard, 100% coded UIViewController, UICollectionView and UICollectionViewCell - works perfect.
here's the code in question:
SceneDelegate not sure if this is relevant, tho.
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 very simple and straight forward...
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 here's the problem: the pushViewController method just doesn't do anything but the modal present works like a charm and I'm not getting what's wrong and why:
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 I set up the Delegate via protocol and it seems that's fine too
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")
}
so, any Idea what's wrong with:
navigationController?.pushViewController(homeViewController, animated: true)
As pointed out by @Michcio this here: window?.rootViewController = UINavigationController(rootViewController: myController)
works half way and as far as I understand it, I'm embedding myController into an UINavigationController which adds the Navigation Bar to the current and following controllers.
But that's not what I need!
What I need is a clean and simple one for the onboarding i.e. MyViewController and the HomeViewController should be one with a Tab- and Navigation Bar
Basically starting from scratch after onboarding.
I used to solve this in the previous version editing the AppDelegate first Method like this (in this example I used Storyboards):
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)
}
}
}
and in the Delegate itself like this:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let isFirstRun = true // logic to determine goes here
if isFirstRun {
showOnboarding()
}
return true
}
but I'm seriously not getting the new SceneDelegate or simply don't understand it
Really would appreciate if someone could past some code here for re-use.
Upvotes: 5
Views: 1347
Reputation: 2866
It didn't work, because you are set MyViewController
as window.rootViewController
. Just change line in SceneDelegate
to:
window?.rootViewController = UINavigationController(rootViewController: myController)
Upvotes: 3