Presenting a specific view controller once immediately after launch screen closes
I went with a slightly different approach to solve this.
I embedded the main app VC in a navigation controller, then pushing the tutorialVC in App Delegate didFinishLaunchingWithOptions.
let tutorialVC = UIStoryboard(name: "FirstTutorial", bundle: nil)
let firstVC = tutorialVC.instantiateViewController(withIdentifier: "TutorialSBID") as UIViewController
if let navigationController = self.window?.rootViewController as? UINavigationController
{
navigationController.pushViewController(firstVC, animated: false)
}
return true
Perform Segue on ViewDidLoad
I answered a similar question where the developer wanted to show a login screen at the start. I put together some sample code for him that can be downloaded here. The key to solving this problem is calling things at the right time if you want to display this new view controller, you will see in the example you have to use something like this
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:YES];
}
I also have an explanation of how segues and storyboards work that you can see here
How to skip 2 views when using navigation controller
In a nutshell, the most straightforward solution is to use -[UINavigationController setViewControllers:animated:]
.
You need to do the following to achieve what you want:
- assign storyboard IDs to all your controllers,
- instantiate all three view controller from the story board (this is lightweight as long as you don't do most of the initialisation work in controller's constructors)
- put them into an array in the same order you have them in storyboard,
- call
-[UINavigationController setViewControllers:]
with the array as the first argument.
That's it. The code in your -[AppDelegate application:didFinishLaunchingWithOptions:]
might look like this (after checking your skipping condition of course):
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc1 = [storyboard instantiateViewControllerWithIdentifier:@"MyAuth"]; //if you assigned this ID is storyboard
UIViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:@"Login"]; //if you assigned this ID is storyboard
UIViewController *vc3 = [storyboard instantiateViewControllerWithIdentifier:@"Details"];
NSArray *controllers = @[vc1, vc2, vc3];
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
[navController setViewControllers:controllers];
If you paste just this to -[AppDelegate application:didFinishLaunchingWithOptions:]
, you'll see that it works immediately.
Dialog box displayed by EKEventStore.authorizationStatus(for:) apparently hidden behind overlay
The problem was not that the dialog box was hidden behind the overlay but that I called EKEventStore
's requestAccess(to:completion:)
synchronously (by waiting after the call for a semaphore that was signaled inside the completion handler) inside application(_:didFinishLaunchingWithOptions:launchOptions:)
. Hence the entire app stalled and the dialog box was not even displayed.
The solution consisted in requesting access asynchronously. The following scheme is currently good enough:
- instance variable
calendarEvent
isnil
if access to anEKCalendar
was not (yet) granted requestAccess(to:completion:)
is called from insideapplication(_:didFinishLaunchingWithOptions:launchOptions:)
calendarEvent
is set to thisEKCalendar
in completion handler ofrequestAccess(to:completion:)
- before reading or writing to calendar app checks if
calendarEvent != nil
- during cycle of run loop with call to
application(_:didFinishLaunchingWithOptions:launchOptions:)
calendarEvent
remainsnil
; app behaves as if calendar were empty - during later cycles of run loop
calendarEvent
has been set; app actually writes to calendar only during those later cycles
Related Topics
What Happens with Constraints When a View Is Removed
Command Compileswift Failed with a Nonzero Exit Code in Xcode 10
Set Background Gradient on Button in Swift
Get Input Value from Textfield in iOS Alert in Swift
Get Latitude/Longitude from Address
Xcode Unit Testing with Cocoapods
Programmatically Linking Uipagecontrol to Uiscrollview
Toplayoutguide in Child View Controller
Presentviewcontroller and Displaying Navigation Bar
In-App Purchase in Swift with a Single Product
How to Build .Ipa for React Native
iOS 8 Photos Framework. Access Photo Metadata
How to Detect Taps on Mkpolylines/Overlays Like Maps.App
Facebook iOS Sdk - Get Friends List
Corenfc Not Reading Uid in iOS