AppDelegate segue alternative pass data
You can't use segue to ViewController
from AppDelegate
, because AppDelegate
is not a ViewController
. Segues are only work with ViewControllers
.
But you can initiate a storyboard identifier from your AppDelegate
to your ViewController
so you can send data.
There is a example for you;
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let yourViewController = storyboard.instantiateViewController(withIdentifier: "yourViewControllerStoryboardIdentifier") as! YourViewControllerClassName
yourViewController.yourProperty = "yourValue"
self.window?.rootViewController = yourViewController
self.window?.makeKeyAndVisible()
return true
}
You can set your Storyboard ID
in your Main.storyboard
. Just select your ViewController
and set storyboard ID section click the Use Storyboard ID checkmark like image.
Perform Segue from App Delegate swift
c_rath's answer is mostly right, but you don't need to make the view controller a root view controller. You can in fact trigger a segue between the top view on the navigation stack and any other view controller, even from the App Delegate. For example, to push a storyboard view controller, you could do this:
Swift 3.0 and Later
// Access the storyboard and fetch an instance of the view controller
let storyboard = UIStoryboard(name: "Main", bundle: nil);
let viewController: MainViewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! MainViewController;
// Then push that view controller onto the navigation stack
let rootViewController = self.window!.rootViewController as! UINavigationController;
rootViewController.pushViewController(viewController, animated: true);
Swift 2.0 and Earlier
// Access the storyboard and fetch an instance of the view controller
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var viewController: MainViewController = storyboard.instantiateViewControllerWithIdentifier("ViewController") as MainViewController
// Then push that view controller onto the navigation stack
var rootViewController = self.window!.rootViewController as UINavigationController
rootViewController.pushViewController(viewController, animated: true)
How to pass Data to Another Viewcontroller?
Follow the Model-View-Controller approach: make a model object that stores data coming from A, B, C, and D before they segue away to the next view controller; at the end of the chain of segues the model will contain data from all four controllers.
At the point when you reach E, its data is stored for it in the model object; it can take it from the model for display.
Passing data between two different storyboards
1/ A good way to do this is to make a separate model object that can be equally addressed from both locations. And the simplest way to do that is to add a property to the @interface
section of your AppDelegate.h
file, eg
@property (nonatomic, strong) NSString* sharedString;
To set and get it, you need to add typed access to the AppDelegate in any file that needs it:
#include AppDelegate.h
Then you can use...
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
//to set (eg in A controller)
appDelegate.sharedString = string;
//to get (eg in B controller)
NSString* string = appDelegate.sharedString;
As an alternative to a property, you could use a static variable in a header file:
static NSString* staticString;
Which would be accessible to any object that #imports
the header file. Not really the Objective-C way though.
For more elaborate cases, you may want to create a singleton object to access your model data.
2/ Try:
[self performSegueWithIdentifier: @"secondViewSegue" sender:self];
Ensure that the Segue is wired from your viewController, not it's Navigation Controller.
xcode 8 swift: unwind segue transfer data is not working
You need to perform unwind and send data as following:
@IBAction func unwindToRaceViewController(sender: UIStoryboardSegue)
{
if let sourceViewController = sender.sourceViewController
as? RaceViewController {
stat = sourceViewController.stat
}
You could refer to this article for unwind segues as alternative to delegate
You could also use delegates to pass data back to the previous controller.
Best practices for Storyboard login screen, handling clearing of data upon logout
Here is what I ended up doing to accomplish everything. The only thing you need to consider in addition to this is (a) the login process and (b) where you are storing your app data (in this case, I used a singleton).
As you can see, the root view controller is my Main Tab Controller. I did this because after the user has logged in, I want the app to launch directly to the first tab. (This avoids any "flicker" where the login view shows temporarily.)
AppDelegate.m
In this file, I check whether the user is already logged in. If not, I push the login view controller. I also handle the logout process, where I clear data and show the login view.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Show login view if not logged in already
if(![AppData isLoggedIn]) {
[self showLoginScreen:NO];
}
return YES;
}
-(void) showLoginScreen:(BOOL)animated
{
// Get login screen from storyboard and present it
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
LoginViewController *viewController = (LoginViewController *)[storyboard instantiateViewControllerWithIdentifier:@"loginScreen"];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:viewController
animated:animated
completion:nil];
}
-(void) logout
{
// Remove data from singleton (where all my app data is stored)
[AppData clearData];
// Reset view controller (this will quickly clear all the views)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MainTabControllerViewController *viewController = (MainTabControllerViewController *)[storyboard instantiateViewControllerWithIdentifier:@"mainView"];
[self.window setRootViewController:viewController];
// Show login screen
[self showLoginScreen:NO];
}
LoginViewController.m
Here, if the login is successful, I simply dismiss the view and send a notification.
-(void) loginWasSuccessful
{
// Send notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"loginSuccessful" object:self];
// Dismiss login screen
[self dismissViewControllerAnimated:YES completion:nil];
}
Share NSArray data between two ViewControllers
There is many ways of doing that. It dependes on the hierarchy of your viewControllers and of your problem.
You could:
Create a singleton : http://www.galloway.me.uk/tutorials/singleton-classes/
Pass this array forward and back with segue/delegate : Passing Data between View Controllers
Put the array as a property of one view controller, pass a weak reference of this viewController to the another, and then access something like viewController1.array
Create one property in each viewController and synchronize them with KVC : http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177i
Etc.
Related Topics
Running Swift Build in Terminal Leading to "Platform Path" Errors
Swift Language Statically or Dynamically Dispatched
Phase 1 and Phase 2 Initialization in Swift
Implementing Swift Protocol Methods in a Base Class
How to Prevent Multiple Instances of the Same Window from Opening in MACos
How to Implement a Generic Struct That Manages Key-Value Pairs for Userdefaults in Swift
Resulting Mtltexture Lighter Than Cgimage
How to Cast from Uint16 to Nsnumber
Why 'Self.Self' Compiles and Run in Swift
Swiftui Share Sheet Crashes iPad