使用Swift和iOS登录屏幕8 Storyboard
我在处理iOS应用程序的登录流程时遇到了很多麻烦。故事板,我想实现的图像低于使用Swift和iOS登录屏幕8 Storyboard
我想实现它提出只有当用户第一次打开应用程序,并在没有登录可选登录屏幕。目前,我将选项卡栏控制器设置为根视图控制器。但我无法弄清楚如何处理这些视图控制器之间的交换。
我试图用下面的代码简单地推入登录屏幕。但是,它不起作用。我相信标签栏控制器不允许推新视图控制器的问题。
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
}
有没有方法可以切换视图控制器,而无需在导航控制器内推动?任何有关如何处理这种登录流的建议将不胜感激。
我用一个“LaunchViewController”来实现这一点,它确定它是否应该显示登录视图或主导航控制器。
将启动标记为在故事板中查看您的初始视图,并在其中写入逻辑以确定要呈现的内容。这个过程对用户来说通常非常快并且不明显。
UPDATE:
正如我在评论中提及了,我走了不同的方向。现在在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()
}
}
}
}
注意StoryboardScene
不是默认类型,我使用https://github.com/AliSoftware/SwiftGen来生成。
我的App Delegate方法看起来像这样。
if window == nil {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
}
if isRestoringState == false {
if let _ = lastUsedAccount {
LaunchViewController.Dashboard.setAsRootviewController()
} else {
LaunchViewController.Login.setAsRootviewController()
}
}
更新与退出方法评论
func handleLogout(notification: NSNotification) {
LaunchViewController.Login.setAsRootviewController(animated: true)
lastUsedAccount = nil
}
您是否编写逻辑来确定要在viewDidLoad()或其他位置呈现哪个? – Kaunteya 2016-04-04 07:23:59
我已经在一个新的应用程序中走了另一个方向,我正在努力,我更喜欢。在'application(application:didFinishLaunchingWithOptions:)'中的App Delegate中,我确定应该呈现哪个视图,并将相应的视图设置为'rootViewController'。用一些示例代码更新了我的答案。 – 2016-04-04 17:26:49
@ChrisWagner你如何处理用户注销?你只是把'window'的'rootViewController'改回''.Login'视图控制器?如果是这样,你在转换过程中会遇到动画不佳的情况吗?在启动注销后,转换回身份验证视图控制器时,我似乎会看到奇怪的动画。 – 2016-10-19 01:25:45
为LoginViewController设置Is Initial View Controller
。
从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)
}
运行您的项目。
这里是我做的,它工作正常:
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
}
这是你的整个didFinishLaunchingWithOptions方法的代码?如果用户登录,你如何转换到第一个控制器?我猜这是自动与故事板完成的...在这种情况下,您正尝试在代码中的错误位置推送此登录视图... – 2015-03-02 20:07:55