RootViewController's constraints get removed after calling VNDocumentCameraViewController - ios

After presenting and dismissing the VNDocumentCameraViewController, I get a black screen. After some research, I found that a few constraints disappear after dismissing the camera view controller.
Here is a comparison of the view hierarchy before and after the VNDocumentCameraViewController.
Changes I noticed:
UILayoutContainerView's constraints are completely gone
RootTabBarContoller's constraints are halved.
"Position and size are ambiguous" sign
And here is the view hierarchy when the VNDocumentCameraViewController is present.
The root view controller is initialized in a scene delegate like this:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else {
return
}
window = UIWindow(windowScene: windowScene)
window?.rootViewController = RootTabBarController()
window?.makeKeyAndVisible()
}
I was thinking to try a storyboard as the initial scene but all my views use XIBs and I could not find how to import them into a storyboard.
Does the root view controller (RootTabBarController in my case) need extra constraints or some other configuration in order to sustain such transitions?

So, the solution was rather trivial. For some reason, the RootTabBarController had view.translatesAutoresizingMaskIntoConstraints = false line that caused the issue with the constraints.
Removing this line solved the issue.

Related

Correct way to get the screen size on iOS, after UIScreen.main deprecation

I always used UIScreen.main.bounds.size to get the screen size on iOS and worked fine.
Now (in iOS 16, I believe) when I try to access the screen size with the "main" instance of UIScreen a warning is displayed:
"main' will be deprecated in a future version of iOS: Use a UIScreen instance
found through context instead: i.e, view.window.windowScene.screen
So my question is:
What is the correct way to get the screen size? for simplicity let's imagine we are on the iPhone with, consequently, only one screen available. Thank you
From a ViewController:
let screenSize = self.view.window?.windowScene?.screen.bounds.size
Per Apple discussion on UIScreen.main deprecation:
Apple discourages the use of this symbol. Use a UIScreen instance
found through context instead. For example, reference the screen that
displays a view through the screen property on the window scene
managing the window containing the view.
Here is an extension to find the UIScreen instance through context:
extension UIViewController {
func screen() -> UIScreen? {
var parent = self.parent
var lastParent = parent
while parent != nil {
lastParent = parent
parent = parent!.parent
}
return lastParent?.view.window?.windowScene?.screen
}
}
For reference, this is the same UIScreen instance associated with the windowScene in the SceneDelegate:
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 = ViewController()
window?.makeKeyAndVisible()
let screen = windowScene.screen
configureNavigationBar()
}

Failed to instantiate the default view controller after switching from .xcodeproj to .xcworkspace

When I create a brand new project in Xcode and choose Storyboard for the interface, I can run the app on my phone just fine.
However, when I do pod install (the only deps I added are pod 'Plaid') and then switch over to the .xcworkspace file, I get this error:
[WindowScene] Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?
I have tried the usual fixes (check Is Initial View Controller etc.)
Appreciate any help, thanks.
You must assign entry point to your project, go to your sceneDelegate file and set it like this:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.backgroundColor = .white // or the color that you prefer
window?.makeKeyAndVisible()
let controller = ViewController() // or the first controller presented in your app
window?.rootViewController = controller
}

The navigation bar for my programmatic side menu won't appear after navigating from a different view

After following a tutorial for making a side menu programmatically without pods I have come upon an issue regarding my navigation. I have my login view set as the root view controller, in which after logging in I will be presented with the home view. When this transition happnes the navigation bar that should be appearing for the side menu is does not appear and thus I can't access my side menu. I know my side menu works because when I set the home view as the root controlle rthe bar shows up allowing me to click the side menu.
Scene delegate:
var window: UIWindow?
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
let nav = UINavigationController()
let mainView = LogInController()
nav.viewControllers = [mainView]
window?.rootViewController = nav
window?.makeKeyAndVisible()
The transitions I use in the log in controller:
let homeView = HomeMenu()
homeView.modalTransitionStyle = .flipHorizontal
homeView.modalPresentationStyle = .overCurrentContext
present(homeView, animated: true, completion: nil)
I do not want to use pods
I am using firebase
I also have a signup
When I leave the home menu and then come back I still want the bar to appear.
Nevermind I instead just added a navigation bar programmatically and from there added accessed my side menu.

Xcode 11, Main Interface fixed with Main.storyboard [duplicate]

This question already has answers here:
Cannot change Main.storyboard's name on iOS 13 [Xcode 11 GM seed 2]
(2 answers)
Closed 3 years ago.
Main Interface is not changing with another storyboard in Xcode 11, it always run with Main.storyboard after changing with another storyboard, I have checked "is initial View Controller" after using a View Controller in new Storyboard.
I have tested in Xcode 10, it was working fine.
Did I miss something in Xcode 11?
In plist.
Swift 5 with iOS 13
One more changes require in info.plist file under Application
Scene Manifest group.
Change name in Application Scene Manifest also.
Additional:
If you want to create the root window without a storyboard, you need removing the Main storyboard file base name and Storyboard Name item from Info.plist, and create the window programmatically in SceneDelegate:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
#available(iOS 13.0, *)
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
// continue to create view controllers for window
}
//......
}
Can you please change "Main storyboard file base name" to your storyboard file name.

SwiftUI SceneDelegate Issue

Within SceneDelegate.swift the following code is returning the error message "Use of unresolved identifier 'ContentView'; did you mean 'ContentMode'?".
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options
connectionOptions: UIScene.ConnectionOptions) {
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIHostingController(rootView: ContentView())
self.window = window
window.makeKeyAndVisible()
}
This error creates a failure in the program build. It's surprising since when I create a new project with the exact same SceneDelegate.swift, there is no issue with ContentView.
If I change ContentView to ContentMode it returns the error 'ContentMode' cannot be constructed because it has no accessible initializers".
Has anyone else had this issue? Just curious where I should start looking or what I have done wrong.
Figured this one out. If anyone else is curious I changed the ContentView.swift file name but didn't update it in SceneDelegate.swift.
So if you change the ContentView.swift file to BetterNameView.swift you need to update the above code in SceneDelegate.swift from ContentView() to BetterNameView()

Resources