ios 在 ViewDidLoad 上执行 Segue
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8221787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Perform Segue on ViewDidLoad
提问by adam0101
In iOS 5 I have a Storyboard with a modal view controller, that I would like to display if its the user's first time in the app, after that I would like to skip this view controller.
在 iOS 5 中,我有一个带有模式视图控制器的 Storyboard,如果用户第一次使用应用程序,我想显示它,之后我想跳过这个视图控制器。
I set an NSDefault key to handle this but when I check to see if this is set and then use performSegueWithIdentifier to initiate the segue, nothing happens. If i put this segue behind a button it works fine...
我设置了一个 NSDefault 键来处理这个问题,但是当我检查是否设置了它,然后使用 performSegueWithIdentifier 来启动 segue 时,没有任何反应。如果我把这个 segue 放在一个按钮后面,它工作正常......
采纳答案by Scott Sherwood
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
我还解释了 segues 和 storyboards 是如何工作的,你可以在这里看到
回答by bearMountain
Loading in ViewDidLoad caused "under-layer" to flash. I solved this by loading my Storyboard programmatically. Thus, under Target/Main Storyboard - leave this blank. Then add the following:
在 ViewDidLoad 中加载导致“下层”闪烁。我通过以编程方式加载我的 Storyboard 解决了这个问题。因此,在目标/主故事板下 - 将此留空。然后添加以下内容:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Load Main App Screen
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
HomeScreenVC *homeScreenVC = [storyboard instantiateInitialViewController];
self.window.rootViewController = homeScreenVC;
[self.window makeKeyAndVisible];
// Load Login/Signup View Controller
UIViewController *mainLoginVC = [storyboard instantiateViewControllerWithIdentifier:@"MainLoginVC"];
[mainLoginVC setModalPresentationStyle:UIModalPresentationFullScreen];
[homeScreenVC presentModalViewController:mainLoginVC animated:NO];
return YES;
}
回答by NJones
The problem is you are adding a second view to the hierarchy before the first is fully added. Try putting your code in:
问题是您在完全添加第一个视图之前向层次结构添加了第二个视图。尝试将您的代码放入:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// Present your modal from here
}
After [super viewDidAppear]
is called you have a fully loaded view to modify.
之后[super viewDidAppear]
是叫你有一辆满载视图进行修改。
回答by EladWeinson
There is no principal problem with performing segues in viewDidLoad (after the call to super of course).
在 viewDidLoad 中执行 segue 没有主要问题(当然是在调用 super 之后)。
The problem is performing segues before the window of the application is made visible. The UIViewController you want to display is part of the main storyboard so it is loaded into memory before the app begins running it's code in the app delegate. In your case, the viewDidLoad is called by iOS before your application window got message: MakeKeyAndVisible.
问题是在应用程序窗口可见之前执行 segue。您要显示的 UIViewController 是主故事板的一部分,因此在应用程序开始运行应用程序委托中的代码之前,它会被加载到内存中。在您的情况下,viewDidLoad 在您的应用程序窗口收到消息之前由 iOS 调用:MakeKeyAndVisible。
The important part is the visibility. Performing a segue on a view hierarchy in which the window is not visible does nothing!
重要的部分是可见性。在窗口不可见的视图层次结构上执行 segue 没有任何作用!
You can try to do something like this:
你可以尝试做这样的事情:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// The window initialized with hidden = YES, so in order to perform the segue we need to set this value to NO.
// After this action, the OS will add the window.rootViewController's view as a subview of the window.
self.window.hidden = NO;
[self.window.rootViewController performSegueWithIdentifier:_IDENTIFIER_ sender:self.window.rootViewController];
// Now that the window is not hidden, we must make it key.
[self.window makeKeyWindow];
return YES;
}
回答by Leon Deriglazov
UPDATE:this solution no longer works in iOS 8.
更新:此解决方案不再适用于 iOS 8。
A correct way to solve your problem is to trigger the segue / present modal view controller in applicationDidBecomeActive:
app delegate method or in a UIApplicationDidBecomeActiveNotification
notification handler.
解决问题的正确方法是在applicationDidBecomeActive:
应用程序委托方法或UIApplicationDidBecomeActiveNotification
通知处理程序中触发 segue/present 模式视图控制器。
Apple's documentation actually advises the same:
Apple 的文档实际上提出了相同的建议:
If your app was previously in the background, you could also use it to refresh your app's user interface.
如果您的应用之前处于后台,您还可以使用它来刷新应用的用户界面。
This solution has the advantage that it works with Main storyboard loading mechanism so that you don't need to load anything manually and write unnecessary code.
此解决方案的优点是它与 Main storyboard 加载机制配合使用,因此您无需手动加载任何内容并编写不必要的代码。
I use this solution successfully on iOS 6.1, 7.0 and 7.1 and it should work on iOS 5 either.
我在 iOS 6.1、7.0 和 7.1 上成功使用了这个解决方案,它也应该在 iOS 5 上工作。
回答by Serge Pedroza
This is how I did it in SWIFT. This also hides the View Controller.
这就是我在 SWIFT 中所做的。这也隐藏了视图控制器。
override func viewWillAppear(animated: Bool) {
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let isloggedIn = prefs.objectForKey("isLoggedIn") as? Bool
if (isloggedIn != false) {
self.view.hidden = true
} else {
self.view.hidden = false
}
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let isloggedIn = prefs.objectForKey("isLoggedIn") as? Bool
if (isloggedIn != false) {
println("this should work")
self.performSegueWithIdentifier("Login", sender: self)
}
}
回答by pbaranski
For Swift:
对于斯威夫特:
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier("toView2", sender: self)
}
For Swift 3:
对于 Swift 3:
DispatchQueue.main.async {
self.performSegueWithIdentifier("toView2", sender: self)
}
回答by Jaseem Abbas
Swift 3
斯威夫特 3
override func viewWillAppear(_ animated: Bool) {
if authPreference.isExist() == true {
self.view.isHidden = true
} else {
self.view.isHidden = false
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
if authPreference.isExist() == true {
navigateToSegue()
}
}
回答by James Jordan Taylor
Updated for Swift 3
为 Swift 3 更新
The code snippet below allows you to load whichever viewController you want. In my case it was a TabBarController if the user had a valid facebook login token. The benefit to this solution over the other Swift 3 solution is that it's instantaneous with no screen flicker.
下面的代码片段允许您加载您想要的任何视图控制器。在我的例子中,如果用户有一个有效的 Facebook 登录令牌,它就是一个 TabBarController。与其他 Swift 3 解决方案相比,此解决方案的优势在于它是即时的,没有屏幕闪烁。
func applicationDidBecomeActive(_ application: UIApplication) {
if FBSDKAccessToken.current() != nil {
self.window?.rootViewController?.present((self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "TabBarController"))!, animated: false, completion: nil)
}
}
回答by GuillermoMP
I had the same problem. Before finding this question, I solved this issue by using async in the main thread. This way, this code will be called by the UI thread right after creating the view.
我有同样的问题。在找到这个问题之前,我通过在主线程中使用 async 解决了这个问题。这样,此代码将在创建视图后立即由 UI 线程调用。
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:@"segueAlbums" sender:self];
});
This code can be called in the viewDidLoad
method.
可以在viewDidLoad
方法中调用此代码。