Ios 自定义导航栏图像应用于每个视图控制器,不符合NSUserDefaults同步

Ios 自定义导航栏图像应用于每个视图控制器,不符合NSUserDefaults同步,ios,iphone,uinavigationbar,nsuserdefaults,Ios,Iphone,Uinavigationbar,Nsuserdefaults,我有一个选项卡栏控制器,由3个选项卡式表视图控制器(时间线、事件和设置)组成,我正在处理主题 如果用户单击设置,他们可以单击“主题”单元格并从各种主题中进行选择 通过使用NSUserDefaults,我将主题保存在SelectThemesTableViewController的didSelectCell中: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

我有一个选项卡栏控制器,由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];
}
在时间线和事件视图控制器中,我正在设置背景,视图中将显示导航栏图像和选项卡栏图像,具体取决于用户选择的单元格,如下所示:

- (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中设置主题时,它会起作用,当我转到Timeline Table视图时,主题会与背景、导航栏和选项卡栏图像一起完全应用。如果我退出应用程序并返回,所有内容仍然存在

但是,问题是:如果我从模拟器或我的设备上的多任务中关闭应用程序,然后重新打开我的应用程序,背景和选项卡栏就是我上次设置的,但是导航栏会回到应用程序委托中应用的默认值。如果我更改为另一个选项卡并返回到时间线,导航栏将更改为之前选定的导航,但问题是加载默认导航栏而不是选定导航栏的初始视图,如果我更改选项卡并返回到时间线选项卡,它将再次显示

我的观点是:

- (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];

}
如果我删除这个viewdide代码,同样的事情也会发生。 我错过什么了吗?为什么导航栏不符合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始终首先运行。在此之后,将调用时间线表视图(初始视图控制器)的视图,其中包含NSLog

这就解释了为什么在应用程序被多任务杀死(或者几个小时没有打开)后,第一次启动应用程序时导航栏会返回默认状态。但是,我不一定需要在AppDelegate中设置代码。起初,应用程序没有主题,因此设置AppDelegate的导航栏很重要。但是现在,我想用一个主题启动应用程序,但是当选择了一个新主题时,不要在应用程序被终止后第一次运行时向前推应用程序代理的导航栏


在此方面的任何帮助都将不胜感激

精简并简化您的解决方案,以便在两个位置使用
UIAppearance
proxy配置所有基于主题的UI:

  • 应用程序代理-使用存储的设置(最好是调用主题管理器)
  • 主题管理器-使用新存储的设置

  • 通过这种方式,您的主题代码被包含和组织,并且您始终应用了适当的主题(而不是某些默认主题)。

    应用程序委派中调用的默认设置在哪里?你在用故事板吗?添加日志并检查代码的运行顺序…谢谢@Wain-将在应用程序代理的didFinishLaunchingWithOptions中调用默认设置。我在didFinishLaunchingWithOptions方法中也有默认的选项卡栏图像,当从多任务中关闭应用程序时不会调用该方法。我在这里为整个应用程序使用所有故事板。登录AppDelegate-在我启动应用程序时会调用它,但在我关闭应用程序时不会被点击,但在我从多任务中终止应用程序时会被调用。谢谢WainSorry@Wain,你对这个问题有什么进一步的想法吗?你添加了日志记录并检查了调用的代码和时间吗?我已经在最后的问题中添加了日志记录中的注释。每次都会在视图出现之前调用AppDelegate。。这就解释了为什么这是工作的方式,但我不知道如何解决这一点..非常感谢@Wain-选项1在这里像一个绝对的对待工作。