8

我有一个 iPhone 应用程序:当您打开该应用程序时,您会看到“LoginView”。如果您登录到应用程序,您会看到一个 TabBarController。在第三个也是最后一个选项卡中,有“注销”按钮。如果单击,您会再次看到“LoginView”。我的问题是,如果您再次登录,您会看到“旧”标签栏,而选定的标签是第三个而不是第一个,并且有一个“注销”按钮。另外,如果用户使用不同的用户登录,请查看前一个用户的旧数据(非常危险)。

这是代码:-Delegate.h:

UITabBarController *tabBarController;
LoginViewController *loginView;

-Delegate.m (didFinishLaunchingWithOptions):

[self.window makeKeyAndVisible];

loginView = [[LoginViewController alloc] init];

if (YES) { /* if the user is not already logged */
    [self.window addSubview:loginView.view];
}

Delegate.m(方法):

- (void)loginComplete {
    [loginView dismissModalViewControllerAnimated:YES];
    [window addSubview:tabBarController.view];
}

- (void)logoutComplete {
    [[tabBarController view] removeFromSuperview];
    [tabBarController release];
    [window addSubview:loginView.view];
}

这是两个不同视图控制器中的两种方法:

- (IBAction)login:(id)sender {

     TabNavisAppDelegate *delegate =
      (TabNavisAppDelegate *) [[UIApplication sharedApplication] delegate];
  [delegate loginComplete];
  }

(注销方法相同)

各位大侠,我该如何解决这个痛苦的问题呢?所以,这里有一个做我想做的应用程序列表:“Foursquare”、“Brightkite”等等。每个都有一个登录屏幕、一个标签栏视图和一个注销按钮。

谢谢大家。

4

4 回答 4

10

对于logout-logout-login的情况,各种事情都需要在注销或下次登录时自行重置,我喜欢创建一个通知,比如“NewUserReset”。需要将自身重置为原始状态的所有内容都会监听通知并运行一个方法来执行它需要的任何类型的重置。标签栏会将按钮标题更改为注销、临时数据结构 nil/zero/release 等。

它很好地将注销与所有必须完成的事情分离,因此您不会尝试从接收注销点击的控制器操作视图控制器和数据存储和视图外观。

发送通知很容易。当用户点击注销按钮时,您将发送如下通知:

[[NSNotificationCenter defaultCenter] postNotificationName:@"JMUserLogout" 
                                                object:nil];

您不必将其称为 JMUserLogout,您只需要一个您会识别的字符串和一些东西——我使用了你的首字母——帮助确保你不会意外发送与通知同名的通知你不知道正在听。

当该通知发出时,已向 defaultCenter 注册以侦听 @"JMUserLogout" 的任何对象都将执行您选择的任何操作。这是您的对象注册的方式(这应该位于某个地方,例如 ViewWillLoad 或对象的初始化方法):

[[NSNotificationCenter defaultCenter] addObserver:self 
                                     selector:@selector(resetForNewUser:)
                                         name:@"JMUserLogout"
                                       object:nil];

那里的选择器 resetForNewUser: 只是通知发出时您要运行的方法的名称。该方法如下所示:

- (void)resetForNewUser:(NSNotification *)notif {
    // DO SOMETHING HERE
}

在它说//在这里做某事的地方,您将添加特定于您的应用程序的代码。例如,您可以将选项卡栏添加为 JMUserLogout 通知的观察者。在其 resetForNewUser: 方法中,您可以将注销按钮的名称更改为 Login。

在保存来自前一个用户的旧数据的 ViewController 或 View 或数据存储中,resetForNewUser 方法将删除所有这些数据并将其设置回新用户应有的方式。例如,如果前一个用户在 UITextField 中输入数据,您将删除文本,yourTextFieldName.text = @"";

最后,重要的是,您还要在对象被释放之前将其作为观察者移除。在注册接收通知的每个对象的 Dealloc 方法中,添加以下内容:

[[NSNotificationCenter defaultCenter] removeObserver:self];

希望这是有道理的。NSNotificationCenter的Apple 文档解释了更多,它们提供了几个使用通知的示例应用程序。

于 2010-12-03T05:41:51.933 回答
0

似乎 tabBarController 没有被释放。[释放前保留计数应为 1] tabBarController 可能保留在某处。检查它的保留计数。

于 2010-12-03T05:35:21.793 回答
0

tabBarController 对象可能已保留在某处。尝试删除它。

并将以下代码用于登录、注销方法

- (void)loginComplete {

    // initialize the tabBarController here. like the following
    if(tabBarController == nil){
    tabBarController = [[UITabBarController alloc] init];

    }
    [loginView dismissModalViewControllerAnimated:YES];
    [window addSubview:tabBarController.view];
}

- (void)logoutComplete {
    [[tabBarController view] removeFromSuperview];
    [tabBarController release];
    tabBarController = nil;
    [window addSubview:loginView.view];
}

这样你的问题就会得到解决。

于 2010-12-03T06:42:24.570 回答
0

如果您想在注销后重置前一个用户的旧数据.. 您所要做的就是重置 UITabBarController 的viewControllers属性。

因此,如果您将 UITabBarController 子类化,则以下代码应将您的应用程序恢复到其原始状态。

    self.viewControllers = @[self.viewControllerOne, self.viewControllerTwo, self.viewControllerThree];

从文档中:

如果您在运行时更改此属性的值,标签栏控制器会在安装新视图控制器之前删除所有旧视图控制器。新视图控制器的选项卡栏项目会立即显示,并且不会动画到位。

于 2015-10-24T00:32:27.703 回答