自定义导航栏图像应用于每个View Controller,不符合NSUserDefaults同步

时间:2014-03-19 11:14:24

标签: ios iphone uinavigationbar nsuserdefaults

我有一个标签栏控制器,由3个选项卡式表视图控制器(时间轴,事件和设置)组成,我正在使用主题。

如果用户点击“设置”,他们可以点击“主题”单元格并从各种主题中进行选择。

通过使用NSUserDefaults,我将主题保存在SelectThemesTableViewController的didSelectCell中:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
    self.selectedTheme = selectedCell.textLabel.text;
    [[NSUserDefaults standardUserDefaults] setObject:self.selectedTheme forKey:@"Theme"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

在时间轴和事件视图控制器中,我在viewWillAppear中设置背景,导航栏图像和标签栏图像,具体取决于用户选择的单元格如下:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.selectedTheme = [[NSUserDefaults standardUserDefaults] objectForKey:@"Theme"];

    if ([self.selectedTheme isEqualToString:@"Blur"])
    {
        // View Background
        UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Purplepink.png"]];
        self.tableView.backgroundView = backgroundImageView;

        // Navigation Bar
        UIImage *navBackgroundImage = [UIImage imageNamed:@"Purplepinknav.png"];
        [[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];

        // Tab Bar
        UIImage *tabBackground = [[UIImage imageNamed:@"SolidPurple.png"]
                                  resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
        [self.tabBarController.tabBar setBackgroundImage:tabBackground];

    }
    else if ([self.selectedTheme isEqualToString:@"Red Slanted"])
    {
        // View Background
        UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"RedSlanted.png"]];
        self.tableView.backgroundView = backgroundImageView;

        // Navigation Bar
        UIImage *navBackgroundImage = [UIImage imageNamed:@"RedSlantedNav.png"];
        [[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];

        // Tab Bar
        UIImage *tabBackground = [[UIImage imageNamed:@"RedSlantedTab.png"]
                                  resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
        [self.tabBarController.tabBar setBackgroundImage:tabBackground];

    }

    else if ([self.selectedTheme isEqualToString:@"Twirl"])
    {
        // View Background
        UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Twirl.png"]];
        self.tableView.backgroundView = backgroundImageView;

        // Navigation Bar
        UIImage *navBackgroundImage = [UIImage imageNamed:@"ReddishBlackNav.png"];
        [[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];

        // Tab Bar
        UIImage *tabBackground = [[UIImage imageNamed:@"ReddishBlackTab.png"]
                                  resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
        [self.tabBarController.tabBar setBackgroundImage:tabBackground];
    }

当我在SelectTheme中设置主题时,它可以工作,当我转到时间轴表视图时,主题完全应用于背景,导航栏和标签栏图像。如果我退出应用程序并重新登录,一切仍然存在。

然而,问题是:如果我从模拟器或我的设备上的多任务中删除应用程序并重新打开我的应用程序,背景和标签栏就是我上次设置的,但导航栏又回来了到App Delegate中应用的默认值。如果我更改为另一个选项卡并返回到时间轴,导航栏将更改为所选导航,但问题是初始视图加载默认导航栏而不是选定的导航栏,如果我更改选项卡并返回到时间轴选项卡,然后再次显示。

我在viewDidDisappear:

- (void)viewWillDisappear:(BOOL)animated
{
    UIImage *navBackgroundImage = [UIImage imageNamed:@"purplynav.png"];
    [[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];
    UIImage *tabBackgroundImage = [UIImage imageNamed:@"purplytab.png"];
    [[UITabBar appearance] setBackgroundImage:tabBackgroundImage];

}

如果删除此viewDidAppear代码,则会发生同样的事情。 我错过了什么吗?为什么导航栏不符合NSUserDefaults?

AppDelegate如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"Is this getting called?");
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
    UIImage *navBackgroundImage = [UIImage imageNamed:@"purplynav.png"];
    [[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];
    UIImage *tabBackgroundImage = [UIImage imageNamed:@"purplytab.png"];
    [[UITabBar appearance] setBackgroundImage:tabBackgroundImage];
    ...
}

编辑:我根据评论添加了一些日志记录。 AppDelegate中didFinishLaunchingWithOptions中的NSLog始终先运行。在此之后,时间轴表视图(初始视图控制器)的viewWillAppear将在那里调用NSLog。

这解释了为什么导航栏在多任务处理(或未打开数小时)之后第一次启动应用程序时返回到默认值。但是,我不一定需要在AppDelegate中设置代码。首先,应用程序没有主题,所以设置AppDelegate的导航栏非常重要。但是现在,我想用一个主题启动应用程序,但是当选择一个新主题时,不要在应用程序运行后第一次推送App Delegate的Nav Bar。

对此的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

修剪并简化您的解决方案,以便在2个位置使用UIAppearance代理配置所有基于主题的UI:

  1. 应用代表 - 使用存储的设置(如果这是对主题管理员的调用,则最好)
  2. 主题管理器 - 使用新存储的设置
  3. 通过这种方式,您的主题代码将被包含和组织,并且您始终应用适当的主题(而不是默认主题)。