iOS 7中的UIBarButtonItem出现问题,这可能是Apple的bug吗?

Lil*_*oke 9 iphone objective-c uibarbuttonitem ios uiappearance

我前段时间看到一篇文章,它在这里:

iOS 6中的用户界面自定义

它显示了iOS 6的自定义.由于我撰写了使用该技术的应用程序的文章,它非常简单,没有任何魔力.

但是,我需要更新我的一个应用程序,在iOS 7下它无法正常工作.看来,UIBarButtonItems的自定义在第一次显示视图时不起作用.如果我解雇视图然后呈现它agin一切正常.看到的内容如下所示:

第一次观看:

在此输入图像描述

第二次:

在此输入图像描述

我在他的例子,我的代码和我写的测试应用程序中看到了这个问题.代码如下:

// Customizing the Back Bar Buttons
UIImage * btBack_30 = [[UIImage imageNamed:@"btBack_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
UIImage * btBack_24 = [[UIImage imageNamed:@"btBack_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 5)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,没有真正的魔法,相当标准,但我找不到任何理由或解释为什么这在iOS 7中不起作用.代码被执行- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions.

我希望有人看到这个,并提供解决方案.谢谢你的帮助!

**注意:有人提出这不是苹果虫,而是设计.我并不是说这是一个苹果问题,它可能更像是我的问题,但是如果你运行任何一个样本或者复制并粘贴下面的代码,很明显它第一次不能正常工作,而后续工作也是如此.这会让我相信api调用是有效的,但要么他们有错误,要么我错过了需要做的事情.

****更新4:**

我根据FruityGeek的建议将MyAppDelegate的init方法中的代码更改为以下内容,但仍然没有运气:

- (instancetype)init
{
    self = [super init];
    if (self)
    {
        //Other UIAppearance proxy calls go here

        [[UIBarButtonItem appearance] setTitleTextAttributes:
         [NSDictionary dictionaryWithObjectsAndKeys:
          //[UIColor colorWithRed:220.0/255.0 green:104.0/255.0 blue:1.0/255.0 alpha:1.0],
          [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
          UITextAttributeTextColor,
          //[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0],
          [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
          UITextAttributeTextShadowColor,
          [NSValue valueWithUIOffset:UIOffsetMake(0.5, 0.5)],
          UITextAttributeTextShadowOffset,
          [UIFont systemFontOfSize:12.0],
          UITextAttributeFont,
          nil]
                                                    forState:UIControlStateNormal];

        // Customizing the Back Bar Buttons
        //ios6 uses whole button background image
        UIImage * btBack_30 = [[UIImage imageNamed:@"btBack_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
        UIImage * btBack_24 = [[UIImage imageNamed:@"btBack_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 5)];
        [[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
        [[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];

        if ([[UIDevice currentDevice].systemVersion integerValue] >= 7)
        {
            //ios7 needs additional chevron replacement image
            UIImage * chevronReplacement = chevronReplacement = [btBack_30 imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
            UIImage * chevronTransitionMaskReplacement = chevronTransitionMaskReplacement = [btBack_30 imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
            [[UINavigationBar appearance] setBackIndicatorImage:chevronReplacement];
            [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:chevronTransitionMaskReplacement];
        }
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

****更新3:**

我已经为示例项目添加了一个dropbox链接.这是上面已经发布的链接的补充,这是一个简单的应用程序,也显示了该问题.两者都可以在iOS 6和iOS 7的模拟器中构建和运行.在iOS 6的情况下,一切都按预期工作.在iOS 7中,如果单击表格单元格并显示下一个视图,则不会显示自定义后退按钮,如果您返回并再次显示该按钮,则会显示该按钮.

我已经愚弄了好几天,所以我希望别人看到它并告诉我我错过了什么.

https://www.dropbox.com/s/oi1bh3emvtbmms0/NavigationBarDemo.zip

这可能很愚蠢,但它可能与我的图像有关吗?我将尝试使用不同的图像并发布更新.

  • 尝试使用不同的图像并没有区别,也使用了上面发布的样本中的图像.这是一个很长的镜头,但由于似乎没有人有更好的想法,但值得一试.

****更新2:**

我已经在另一个测试应用程序中尝试了这个并将代码移动到应用程序委托的初始化,但它仍然无法正常工作.我在此发布此内容以及顶部链接的原始作者网站.再加上另一个论坛,但似乎没有人有解决方案.

我想知道这可能是一个Apple bug吗?

****更新1:**

已将代码didFinishLaunchingWithOptions移至willFinishLaunchingWithOptionsinit,但仍然无法正常工作.

***** INIT METHOD FROM AppDelegate.m

- (id)init
{
    // Create resizable images
    UIImage *gradientImage44 = [[UIImage imageNamed:@"navBar_44"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
    UIImage *gradientImage32 = [[UIImage imageNamed:@"navBar_32"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];

    // Set the background image for *all* UINavigationBars
    [[UINavigationBar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone];

    // Customize the title text for *all* UINavigationBars
    [[UINavigationBar appearance] setTitleTextAttributes:
     [NSDictionary dictionaryWithObjectsAndKeys:
      [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
      UITextAttributeTextColor,
      [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
      UITextAttributeTextShadowColor,
      [NSValue valueWithUIOffset:UIOffsetMake(1, 1)],
      UITextAttributeTextShadowOffset,
      [UIFont boldSystemFontOfSize:18.0],
      UITextAttributeFont,
      nil]];

    // Customizing the NavBar Buttons
    UIImage * button30 = [[UIImage imageNamed:@"btButton_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
    UIImage * button24 = [[UIImage imageNamed:@"btButton_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
    [[UIBarButtonItem appearance] setBackgroundImage:button30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setBackgroundImage:button24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];

    [[UIBarButtonItem appearance] setTintColor:[UIColor whiteColor]];

    [[UIBarButtonItem appearance] setTitleTextAttributes:
     [NSDictionary dictionaryWithObjectsAndKeys:
      //[UIColor colorWithRed:220.0/255.0 green:104.0/255.0 blue:1.0/255.0 alpha:1.0],
      [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
      UITextAttributeTextColor,
      //[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0],
      [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
      UITextAttributeTextShadowColor,
      [NSValue valueWithUIOffset:UIOffsetMake(0.5, 0.5)],
      UITextAttributeTextShadowOffset,
      [UIFont systemFontOfSize:12.0],
      UITextAttributeFont,
      nil]
                                                forState:UIControlStateNormal];

    // Customizing the Back Bar Buttons
    UIImage * btBack_30 = [[UIImage imageNamed:@"btBack_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
    UIImage * btBack_24 = [[UIImage imageNamed:@"btBack_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 5)];
    [[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];

    return [super init];
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*d H 5

它确实看起来像一个Apple bug,你应该用bug报告器输入一个bug.也就是说,我可以给你一个相对无痛的解决方法:将此代码添加到RecipetTableViewController:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.title = @"Recipe Book";

    UIBarButtonItem *it = [[UIBarButtonItem alloc] initWithTitle:self.title style:UIBarButtonItemStylePlain target:nil action:NULL];
    UIImage * btBack_30 = [[UIImage imageNamed:@"btBack_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
    [it setBackButtonBackgroundImage:btBack_30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    self.navigationItem.backBarButtonItem = it;
}
Run Code Online (Sandbox Code Playgroud)

编辑:你可以重复这个错误,如果感兴趣,引用它的bug越多苹果将修复它:

BUG:15506447

状态:OpenProduct:iOS版

2013年11月19日下午03:53

摘要:在按钮的第二次出现之前,为后栏按钮项设置UIBarButtonItem外观代理没有任何影响.

重现步骤:在appDelegate中,在出现任何内容之前,添加以下语句:

UIImage*gradientImage44 = [[UIImage imageNamed:@"navBar_44"] resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)]; UIImage*gradientImage32 = [[UIImage imageNamed:@"navBar_32"] resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)]; //为所有 UINavigationBars 设置背景图像[[UINavigationBar外观] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault]; [[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone];

预期结果:首次按下viewController时,其后退按钮中包含图像.

实际结果:第一次出现时,没有图像.再次按下视图.实际上,当你第一次点击按钮时它会出现,但是当按钮第一次出现时却不会出现.

版本:Xcode 5.0.1,iOS 7.0.3

注意:在导航控制器的根视图控制器中添加它可使其工作:

  • (void)viewDidLoad {[super viewDidLoad];

    self.title = @"食谱书"; UIBarButtonItem*it = [[UIBarButtonItem alloc] initWithTitle:self.title style:UIBarButtonItemStylePlain target:nil action:NULL]; UIImage*btBack_30 = [[UIImage imageNamed:@"btBack_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0,13,0,5)]; [it setBackButtonBackgroundImage:btBack_30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; self.navigationItem.backBarButtonItem = it; }

附加的演示项目显示了问题.

组态:

附件:'DynamicsCatalog.zip'已成功上传.

编辑:我很高兴再次说,在bug记者中输入错误,有时确实有效!