【发布时间】:2013-11-15 20:18:36
【问题描述】:
不久前我看到一篇文章,在这里:
User Interface Customization in iOS 6
它显示了针对 iOS 6 的自定义。自从我写了使用该技术的应用程序的文章以来,它非常简单,没有什么神奇之处。
但是,我需要更新我的一个应用程序,但在 iOS 7 下它无法正常工作。似乎 UIBarButtonItems 的自定义在第一次呈现视图时不起作用。如果我关闭视图然后再次呈现它一切正常。所见即所得:
首次展示:
第二次:
我在他的示例、我的代码和我编写的测试应用程序中看到了这个问题。代码如下:
// 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];
正如您所见,没有真正的魔法,非常标准,但我找不到任何原因或解释为什么这在 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;
}
**** 更新 3:**
我已将 Dropbox 链接添加到示例项目。这是上面已经发布的链接的补充,该链接是一个简单的应用程序,也显示了问题。两者都可以在 iOS 6 和 iOS 7 的模拟器中构建和运行。在 iOS 6 的情况下,一切都按预期工作。在 iOS 7 中,如果您单击表格单元格并呈现下一个视图,则不会显示自定义后退按钮,如果您返回并再次呈现该按钮,则会出现该按钮。
这几天我一直在开玩笑,所以我希望其他人能看到它并告诉我我错过了什么。
https://www.dropbox.com/s/oi1bh3emvtbmms0/NavigationBarDemo.zip
这可能很愚蠢,但这可能与我的图像有关吗?我将尝试使用不同图像的示例并发布更新。
- 尝试使用不同的图像并没有区别,还使用了上面发布的示例中的图像。这是一个很长的尝试,但由于似乎没有人有更好的想法,但值得一试。
**** 更新 2:**
我已经在另一个测试应用程序中尝试过这个并将代码移动到 init 遇到了应用程序委托,它仍然无法正常工作。我有这个 张贴在这里以及链接的原始作者网站在 最佳。加上另一个论坛,但似乎没有人有解决方案。
我想知道这是否是 Apple 的错误?
**** 更新 1:**
将代码从 didFinishLaunchingWithOptions 移动到 willFinishLaunchingWithOptions 和 init,但它似乎仍然无法正常工作。
***** 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];
}
【问题讨论】:
-
胡思乱想——在视图最初呈现后,你会去外观代理吗?与建立根视图控制器相关的代码在哪里?
-
我在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 中执行此操作。在 AppDelegate.m
-
将您的演示项目放在 Dropbox 上,以便其他人可以查看(并修复代码)。
-
一只小鸟告诉我你应该用最新的 7.1 beta 重新测试... :-)
-
有什么解决办法吗? iOS 12 似乎仍然是 2019 年的问题!
标签: ios iphone objective-c uibarbuttonitem uiappearance