xcode 带有 Swift 和 iOS 8 Storyboard 的登录屏幕
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28817519/
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
Login Screen with Swift and iOS 8 Storyboard
提问by user3684980
I have having a lot of trouble handling the login flow of my iOS app. An image of the storyboard I am trying to achieve is below
我在处理 iOS 应用程序的登录流程时遇到了很多麻烦。我试图实现的故事板的图像如下
I am trying to achieve an optional login screen which is presented only when a user first opens the app and has not logged in. Currently, I have the Tab Bar Controller set as the root view controller. I can not figure out how to handle swapping between these view controllers, however.
我正在尝试实现一个可选的登录屏幕,该屏幕仅在用户首次打开应用程序且尚未登录时显示。目前,我将 Tab Bar Controller 设置为根视图控制器。但是,我不知道如何处理这些视图控制器之间的交换。
I have tried to simply push the login screen with the following code. However, it does not work. I believe the problem that a tab bar controller is not allowed to push new view controllers.
我尝试使用以下代码简单地推送登录屏幕。但是,它不起作用。我相信标签栏控制器不允许推送新视图控制器的问题。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//stuff
if userLoggedIn {
// Do nothing
} else {
//get access to login view
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var viewController = storyboard.instantiateViewControllerWithIdentifier("signupView") as UIViewController;
// Then push login view
var rootViewController = self.window!.rootViewController as UITabBarController;
rootViewController.pushViewController(viewController, animated: true)
}
// Override point for customization after application launch.
return true
}
Is there a way to switch view controllers without pushing within a navigation controller? Any advice on how to handle this sort of login flow would be greatly appreciated.
有没有办法在不推入导航控制器的情况下切换视图控制器?任何有关如何处理此类登录流程的建议将不胜感激。
回答by Chris Wagner
I achieve this with a "LaunchViewController" that determines if it should present the Login view or the main navigation controller.
我使用“LaunchViewController”来实现这一点,它决定了它是否应该显示登录视图或主导航控制器。
Mark the launch view your initial view in the storyboard and write the logic in there to determine which to present. This process is often very quick and unnoticeable to the user.
在故事板中将启动视图标记为您的初始视图,并在其中编写逻辑以确定要呈现的视图。这个过程通常非常快速并且用户不会注意到。
UPDATE:
更新:
As mentioned in my comment I've gone a different direction. Now in the App Delegate's application(application:didFinishLaunchingWithOptions:)
method I perform the logic necessary to determine which view should be the rootViewController
and set it there using the following.
正如我在评论中提到的,我走了不同的方向。现在在 App Delegate 的application(application:didFinishLaunchingWithOptions:)
方法中,我执行必要的逻辑来确定哪个视图应该是 ,rootViewController
并使用以下内容将其设置在那里。
extension AppDelegate {
enum LaunchViewController {
case Login, Dashboard
var viewController: UIViewController {
switch self {
case .Login: return StoryboardScene.Login.LoginScene.viewController()
case .Dashboard: return StoryboardScene.Dashboard.initialViewController()
}
}
/// Sets `UIWindow().rootViewController` to the appropriate view controller, by default this runs without an animation.
func setAsRootviewController(animated animated: Bool = false) {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let window = appDelegate.window!
let launchViewController = viewController
log.info?.message("Setting \(launchViewController.dynamicType) as rootViewController")
if let rootViewController = window.rootViewController where rootViewController.dynamicType != launchViewController.dynamicType && animated {
let overlayView = UIScreen.mainScreen().snapshotViewAfterScreenUpdates(false)
launchViewController.view.addSubview(overlayView)
UIView.animateWithDuration(0.3, animations: {
overlayView.alpha = 0.0
},
completion: { _ in
overlayView.removeFromSuperview()
});
}
window.rootViewController = launchViewController
window.restorationIdentifier = String(launchViewController.dynamicType)
if window.keyWindow == false {
window.makeKeyAndVisible()
}
}
}
}
Note that StoryboardScene
is not a default type, I am using https://github.com/AliSoftware/SwiftGento generate that.
请注意,这StoryboardScene
不是默认类型,我使用https://github.com/AliSoftware/SwiftGen来生成它。
My App Delegate method looks something like this.
我的 App Delegate 方法看起来像这样。
if window == nil {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
}
if isRestoringState == false {
if let _ = lastUsedAccount {
LaunchViewController.Dashboard.setAsRootviewController()
} else {
LaunchViewController.Login.setAsRootviewController()
}
}
UPDATE with Logout method for Comment
使用注销方法更新评论
func handleLogout(notification: NSNotification) {
LaunchViewController.Login.setAsRootviewController(animated: true)
lastUsedAccount = nil
}
回答by karl j
Here is what i did and it works fine :
这是我所做的并且工作正常:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if (!AppData.sharedInstance.loggedIn) {
let signInNavigation = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("SignInNavigationControllerIdentifier") as? UINavigationController
self.window!.rootViewController = signInNavigation;
}
return true
}
回答by Mohammad Nurdin
Set Is Initial View Controller
for LoginViewController.
Is Initial View Controller
为 LoginViewController设置。
Remove from AppDelegate.swift
and place it in LoginViewController
.
从 中取出AppDelegate.swift
并放入LoginViewController
.
if userLoggedIn {
// Do nothing
} else {
//get access to login view
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var viewController = storyboard.instantiateViewControllerWithIdentifier("signupView") as UIViewController;
// Then push login view
var rootViewController = self.window!.rootViewController as UITabBarController;
rootViewController.pushViewController(viewController, animated: true)
}
Run your project.
运行你的项目。