2

伙计们,

我遇到了一些导航逻辑问题。目前我有一个简单的两个标签标签栏应用程序。但我想在前面显示一个登录屏幕。所以这将是一个 UIView。

目前代码如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    UIViewController *viewController1 = [[roosterViewController alloc] initWithNibName:@"roosterViewController" bundle:nil];
    UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];

    self.tabBarController = [[UITabBarController alloc] init];
    self.tabBarController.viewControllers = @[viewController1, viewController2];
    self.window.rootViewController = self.tabBarController;
    [self.window makeKeyAndVisible];

    return YES;
}

所以这推动了一个简单的tabcontroller。好吧,现在我想要一个登录屏幕。所以这将是一个简单UIView的推动标签栏控制器。但我似乎看不到如何做到这一点的逻辑。

我一直在尝试展示一个模态视图控制器,但问题是:标签栏将在后台加载。因为我需要用户名/密码信息才能在 tabbarview 上工作,所以这不起作用。

我的逻辑是:

委托 > 加载 loginViewController > 加载标签栏控制器

但是,然后我需要能够“注销”。所以我需要销毁标签栏控制器并显示登录屏幕。

对此有什么想法吗?

4

5 回答 5

1

如前所述,登录为rootView,如果登录成功,则启用其他tabbarButtons,否则不要像这样启用它们。最初在视图加载时将bool设置为false,然后如果成功启用tabbar按钮,则不启用。

login = TRUE;


UITabBarItem *reportit = [[[[self tabBarController]tabBar]items] objectAtIndex:2];
[reportit setEnabled:TRUE];

else {

UITabBarItem *reportit = [[[[self tabBarController]tabBar]items] objectAtIndex:2];
[reportit setEnabled:FALSE];

}

于 2012-12-17T23:56:06.487 回答
1

你可以这样做:

您可以创建您的 AppDelegate 符合的协议。

@protocol Authenticator <NSObject>
@required
- (void)authenticateWithUsername:(NSString *)username andPassword:(NSString *)password;
- (bool)authenticated;
@optional
- (void)authenticationSuccess;
- (void)authenticationFailure;

...

@interface AppDelegate : UIResponder <UIApplication, Authenticator>
@property (readonly, nonatomic, assign) bool loggedIn;

...

@implementation AppDelegate
@synthesize loggedIn = _loggedIn;

- (void)authenticateWithUsername:(NSString *)username andPassword:(NSString *)password
{
   //if success
      _loggedIn = YES;
   //check if app responds to the optional authenticateSuccess method
   //call it if it does
   //else fail
      //do stuff
}

- (bool)authenticated
{
   if (_loggedIn != NULL) {
      return _loggedIn;
   }
   //do other stuff
}

...

我对正确的objective-c约定和语法有点模糊,所以如果我有一些错误,请原谅我,但无论如何这是一些逻辑和伪代码可以解决。根据您的需要进行调整。

我希望这有帮助。

编辑:

我想我的答案有点未完成。在我看来,您问题的答案似乎与某种身份验证结构密切相关。如果您的应用程序与身份验证密切相关,那么为什么不通过身份验证结构控制其流程。我想这就是我的观点,并且由于所有这些都可以在您的应用程序委托中方便且容易地获得,您可以在任何您想要的地方调用这些方法,因此让您的身份验证逻辑决定例如显示哪个视图控制器。

于 2012-12-17T18:45:53.760 回答
0

我建议您将登录屏幕设置为 root。登录成功后,您只需将窗口的根目录更改为标签栏控制器,并带有漂亮的动画。

于 2012-12-17T17:04:51.080 回答
0

我建议您像现在一样设置选项卡栏,但在 makeKeyAndVisible 之后立即实例化并呈现登录视图控制器,而不使用动画。

这样,一旦应用程序启动,用户就不会看到 tabBarController,而只会看到模态显示的登录屏幕。登录完成后,您只需关闭登录视图控制器并在其下方出现....鼓起标签栏控制器!

于 2012-12-17T17:30:50.437 回答
0

扩展Levi 的答案,这就是您连续切换根视图控制器的方式(带有动画)。只需添加此扩展名:

extension UIViewController 
{
    func transitionToRootViewController(viewController:UIViewController)
    {
        UIView.transitionWithView(self.view.window,
            duration: 0.3,
            options: UIViewAnimationOptions.TransitionCrossDissolve,
            animations: {
                window.rootViewController = viewController
            },
            completion: nil
        )
    }
}

...到UIViewController类(这将使您的所有transitionToRootViewController ()视图控制器都可以使用该方法),并在退出视图控制器上调用它,传递进入视图控制器(您可能从一个单独的故事板实例化,谁知道...)作为参数。

(基本思想取自这里。我稍微简化了代码)

但请注意:我尝试使用此代码插入一个标签栏控制器,其选定的索引(标签)包含一个导航控制器。在过渡动画期间,导航控制器的导航栏“低于”状态栏(运营商、时钟、电池电量),并且只有在过渡动画完成后,它才会立即“跳”到它的位置,从而造成一个可怕的分散注意力(且未抛光)影响。

我通过将以下代码添加到嵌入在导航控制器中的子视图控制器来修复它:

override func viewWillAppear(animated: Bool)
{
    super.viewWillAppear(animated)

    self.navigationController?.navigationBar.layer.removeAllAnimations()
    // ^ THIS
}

(此修复取自此论坛。)

我还没有检查过,但是当您转换到导航控制器(或任何UIViewController碰巧附有导航栏的普通香草)时,无论它是否嵌入在标签栏控制器中,都可能会出现同样的问题。

于 2015-08-13T01:13:53.363 回答