UIkit back to root navigation view controller programmatically - swift

my problem is somewhere in my app I want to redirect my root navigation view
but I didn't.
in my scene delegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
window?.rootViewController = UINavigationController(rootViewController: ViewController())
window?.makeKeyAndVisible()
}
when I want to redirect my rootViewController I used
self.navigationController?.popToRootViewController(animated: true)
but didn't work.
this code redirect me just my ViewController. there is no navigation bar, navigation bar buttons ect.
can anyone help me ?
i have tried everything in this
link
there is no solution for me.
i want to add some pictures about my code:
here is my sceneDelegate
here is my go to root function
i want to see this screen after the go root function
however I see this...

Related

Could not find keyboard scene delegate for interaction view

Below iOS 13 my UITextField correctly launches a keyboard and lets the user type in their answer.
Above iOS 13, textFieldDidBeginEditing() is triggered when I tap on the text field, but the keyboard is not shown, so the user cannot give their answer .
Debug console doesn't immediately throw any errors, but eventually the following message comes up, which I think is the key:
Could not find keyboard scene delegate for interaction view
I think the error appears in the later iOSs because scenes become the main thing - and somewhere I needed to set up a delegate to allow the keyboard to appear over the fron of the first scene.
No idea how to do this though!
My UITextField is totally standard. To reproduce the error, I have the following set up code in my SceneDelegate
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let windowScene = UIWindowScene(session: session, connectionOptions: connectionOptions)
self.window = UIWindow(windowScene: windowScene)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "VC" )
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
guard let _ = (scene as? UIWindowScene) else { return }
}
In my actual app - I use this subroutine to launch a tutorial if the user is new (i.e. I need to be able to change the starting view controller)
Something appears to be out of sorts in your SceneDelegate function scene().
Try this code which I grabbed from another project I have at hand.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
self.window?.rootViewController = ViewController()
self.window?.makeKeyAndVisible()
}

Jump to a specific viewcontroller xcode

I have 6 view controllers embed in a navigation controller. Let says the user open the app and used the view controller 1 and 2 and then closed the app. How can I make him jump to a specific view controller once he reuses the app?
you can add some variable on the userDefault for check the status of the user, and in the scendedelagate add some validation for move the application on the view controller that you want.
for instance.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
if "your variable UserDefaults variable saved" {
// setupViewController
window?.rootViewController = SomeViewController()
}else{
window?.rootViewController = NormalViewController()
}
}
In the code of above I setup different launch screen depends of the userDefault that I saved, setup the rootViewController.

Setup managedObjectContext on SceneDelegate SwiftUI

I followed a tutorial of an Onboarding screen but it seems it's mostly an adaptation of UIKit, on AppDelegate I get the following error in purple:
Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x6000018d5880>
I believe it's the way it's setup in SceneDelegate that the managedObjectContext is not being passed along to the next screen, here is how I have it:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
// Set the MotherView as the root view
window.rootViewController = UIHostingController(rootView: MotherView().environmentObject(ViewRouter()))
self.window = window
window.makeKeyAndVisible()
}
}
That works if I don't use core data of course. How can Integrate ViewRouter() here:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Get the managed object context from the shared persistent container.
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
// Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath.
// Add `#Environment(\.managedObjectContext)` in the views that will need the context.
let contentView = MotherView().environment(\.managedObjectContext, context)
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
// Set the MotherView as the root view
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
I went to this post but it doesn't do the trick for me, is there a way I could fix this in the SceneDelegate?
Attach environment object to constructed content view in any place, for example as below
let contentView = MotherView()
.environment(\.managedObjectContext, context)
.environmentObject(ViewRouter())

Why is manually setup root view controller showing black screen?

I have manually setup a root view controller for iOS 13 using Xcode 11, Beta 5. Deleted references to main in the deployment info including removing reference to main in info.plist which I never found myself having to do prior to iOS 13. Setup for window is done in SceneDelegate, nested in willConnectTo function. Normally the app would crash if I missed a step. Now I'm getting a blank black screen instead of seeing what my view controller is setup for, say a red background. All of this use to work prior to beta 5.
Have performed erase all content and settings on the simulator. Cleared the build folder and have ran the app on a physical device. Also have used another computer with Xcode 11, beta 5. All results to the same blank black screen. What am I missing?
Here is my manual setup for root view controller in SceneDelegate file nested in willConnectTo function:
let viewCon = ViewController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = viewCon
window?.makeKeyAndVisible()
To ensure you see your root view controller in iOS 13 when everything is done programmatically, you must do the following:
In the scene delegate, you must create the window instance and the root view controller:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let winScene = (scene as? UIWindowScene) else { return }
// Create the root view controller as needed
let vc = ViewController()
let nc = UINavigationController(rootViewController: vc)
// Create the window. Be sure to use this initializer and not the frame one.
let win = UIWindow(windowScene: winScene)
win.rootViewController = nc
win.makeKeyAndVisible()
window = win
}
}
Your Info.plist has to have the "Application Scene Manifest" entry. Below it should be the "Enable Multiple Windows" entry. Set to YES or NO as appropriate to your app. Optionally you should also have the "Scene Configuration" entry.
All of these entries are added by Xcode when you check the "Supports multiple windows" setting on the General tab of your target. This will default the "Enable Multiple Windows" entry to YES so you can change that to NO if you want scenes but not multiple windows.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
self.window = window
let mainstoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "YourVCName") as! YourVCName
navigationController = UINavigationController(rootViewController: newViewcontroller)
window.rootViewController = navigationController
window.makeKeyAndVisible()
}
try this code!!
if you are using ios 13 and your xcode is updated then you should set your root view controller in scene delegate instead of app delegate.
I faced the same problem by the time, I know someone has solved this issue, however, I just wanna share my approach.
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyBoard.instantiateViewController(withIdentifier: "HomeScreen") as? HomeScreen
self.window?.rootViewController = initialViewController
I used this simple code instead, and it works like a charm : )

push ViewController without storyboard

I try to push a view controller from the main ViewController like this (Swift 4):
#objc func childAction(sender: UIButton!) {
print("Child button tapped")
let vc = childDetailViewController()
self.navigationController?.pushViewController(vc, animated: true)
}
The text is printed, but the viewController is not pushed. What did I missed?
Possible that self.navigationController is nil.
Try to present it: self.present(vc, animated: true)
UPD
Also if it does not help, try temporary change your childDetailViewController to UIViewController() and see what happens. If you see the empty white screen after tap then the problem is on childDetailViewController
Inside AppDelegate's didFinishLaunchingWithOptions do
let fir = FirstVC()
self.window?.rootViewController = UINavigationController(rootViewController: fir)
Then this
self.navigationController?.pushViewController(vc, animated: true)
should work
From Xcode 11 you might have noticed that along with the default files like above, a new file is created named as SceneDelegate.swift. From iOS 13 and later, SceneDelegate takes up some responsibilites from AppDelegate. In particular related to UIWindow from AppDelegate is now UIScene in SceneDelegate. An app can have more than one scene which mostly handles application interface and app content. So, the SceneDelegate is responsible for what’s displayed on the screen in terma of UI and data.
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 vc = ViewController()
let navigationView = UINavigationController(rootViewController: vc)
window?.rootViewController = navigationView
window?.makeKeyAndVisible()
}