我有一个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];
}
以下是两个不同viewcontrollers中的两种方法:
- (IBAction)login:(id)sender {
TabNavisAppDelegate *delegate =
(TabNavisAppDelegate *) [[UIApplication sharedApplication] delegate];
[delegate loginComplete];
}
(注销方法相同)
伙计们,我该如何解决这个痛苦的问题? 所以,这里有一个我想要的应用程序列表:“Foursquare”,“Brightkite”等。 每个人都有一个登录屏幕,一个标签栏视图和一个注销按钮。
谢谢@ everyone。
答案 0 :(得分:10)
对于login-logout-login情况,其中各种事情需要在注销或下次登录时自行重置,我喜欢创建通知,例如“NewUserReset”。需要将自身重置为原始状态的所有内容都会侦听通知,并运行一种方法来执行所需的任何重置。标签栏会将按钮标题更改为注销,临时数据结构为零/零/自行释放等。
它很好地将注销与所有必须完成的操作分离,因此您不会尝试操作视图控制器和数据存储,也不会从接收注销点击的控制器中查看外观。
发送通知很简单。当用户点击“注销”按钮时,您将发出如下通知:
[[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或视图或数据存储中,它保存来自前一个用户的旧数据,resetForNewUser方法将删除所有这些数据并将其设置回新用户之前的方式。例如,如果前一个用户在UITextField中输入数据,则会删除文本yourTextFieldName.text = @“”;
最后,在取消分配之前,还要将对象作为观察者移除,这一点很重要。在注册接收通知的每个对象的Dealloc方法中,添加以下内容:
[[NSNotificationCenter defaultCenter] removeObserver:self];
希望这是有道理的。 Apple documentation for NSNotificationCenter解释了更多内容,它们提供了几个使用通知的示例应用。
答案 1 :(得分:0)
似乎tabBarController没有被发布。 [发布前保留计数应为1] tabBarController可能会保留在某处。检查它的保留计数。
答案 2 :(得分: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];
}
这样你的问题就能解决了。
答案 3 :(得分:0)
如果要在注销后重置以前用户的旧数据,您只需重置UITabBarController的 viewControllers 属性即可。
因此,如果您是UITabBarController的子类,则以下代码应将您的应用程序恢复到其原始状态。
self.viewControllers = @[self.viewControllerOne, self.viewControllerTwo, self.viewControllerThree];
来自文档:
如果在运行时更改此属性的值,则选项卡栏控制器会在安装新视图控制器之前删除所有旧视图控制器。新视图控制器的标签栏项目会立即显示,并且不会动画到位。