自定义UINavigationBar字体

时间:2012-04-11 16:21:12

标签: ios ios5

我正在尝试自定义我的UINavigationBar字体,在我的应用代理application:didFinishLaunchingWithOptions中使用以下iOS 5代码:

if ([[UINavigationBar class] respondsToSelector:@selector(appearance)]) 
{
    [[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: 
                                                          [UIColor whiteColor], UITextAttributeTextColor,
                                                          [UIColor blackColor], UITextAttributeTextShadowColor,
                                                          [NSValue valueWithUIOffset:UIOffsetMake(1, 0)], UITextAttributeTextShadowOffset,
                                                          [UIFont fontWithName:kDefaultFont size:0.0], UITextAttributeFont, 
                                                          nil]];
}

它工作正常,导航栏使用我的字体呈现。大。

我发现references建议您可以使用零字体大小,它会调整字体大小以适合您的导航栏(对于横向布局的较短导航栏使用略小的字体) 。它确实选择了适合导航栏高度的字体大小。但看起来如果你从纵向转向横向和背面,导航栏的标题标签的宽度会被搞砸,所以当你第一次看到它时,显示为“Long Titlebar”的标题看起来很好在纵向方向,当你在横向中查看时看起来很好(使用相应较小的字体),但当我回到肖像时,字体正确地恢复为较大的字体,但标题文本本身被截断,变为“长... “尽管有足够的空间可以获得完整的冠军头衔。当使用0.0?

的字体大小时,有没有其他人看到过这种行为

显然,我可以指定一个实际的字体大小(在这种情况下,我没有看到这种截断行为),但后来我手动确定要使用的大小。更糟糕的是,横向和纵向的字体大小相同,所以现在我使用的字体大小适合较短的横向导航栏标题,并且标题小于它需要在较高的纵向导航栏中。

有没有人有使用setTitleTextAttributes更改[UINavigationBar appearance]字体的经验,使得字体大小在纵向和横向之间发生变化,但是在没有标题截断时你去景观后回到肖像?我即将寻求各种麻烦的解决方法,但如果您对此问题有任何经验,请告诉我。

更新

在向Apple提交此错误的过程中,我决定演示如何重现该问题:

  1. 在Xcode 4.3.2中创建新的iOS Master-Detail应用程序。

  2. 将上述setTitleTextAttributes代码放入app delegate application:didFinishLaunchingWithOptions(我使用字体@“GillSans”)。

  3. 转到MasterViewController并添加说self.title = @"Long Title";

  4. 的行
  5. 注释掉UIBarButtonItem *addButton代码。

  6. 运行程序。注意标题正确地说“长标题”。旋转到风景。看起来还不错。旋转回肖像,标题现在说“长......”,即使有足够的空间。

  7. 奇怪的是,如果您恢复UIBarButtonItem *addButton代码,则标题可以正常工作。但是,如果您要么删除UIBarButton项目,或者使用使用initWithTitle而不是initWithBarButtonSystemItem的按钮替换它,那么在从纵向旋转到横向然后再回到纵向后,您会遇到导航栏标题的问题

5 个答案:

答案 0 :(得分:3)

顺便说一句,我忽略了指出Apple回复了我的错误报告,承认这是一个已知的问题。希望很快就能解决!

答案 1 :(得分:1)

我认为一个好的解决方案是在设备轮换后刷新Navbar的标题。像

这样的东西
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {

        self.navigationItem.title = @"Your title";

}

希望这有帮助!

答案 2 :(得分:1)

基于@Abramodj的响应(不起作用),我尝试了这个。据推测,该解决方案没有发生任何事情,因为系统注意到文本实际上没有改变。切换到空,然后重新排序。

经过测试,绝对适用于iOS5.0。

// iOS5 has a bug where if you switch orientation the title bar text gets cut off...
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation     {
    self.navigationItem.title = @"";
    self.navigationItem.title = @"Your Title";
}

答案 3 :(得分:1)

以下是我对此问题的解决方法,以下是我的解决方法实现旁边出现的注释,以提醒自己为什么我实现了这段代码:

// when using an appearance proxy to set a custom font for the navigation bar (generally in
// application:didFinishLaunchingWithOptions: in the appDelegate code) for both iOS 5 & 6,
// there's a glitch that incorrectly auto-truncates the title in the following cirumstances:
//
// 1) when a 0.0 value is used for UITextAttributeFont in the titleTextAttributes dictionary
//    and a device/simulator running pre-iOS 5 rotates back to portrait from landscape
//    solution: perform [self.navigationController.navigationBar setNeedsLayout] in
//              didRotateFromInterfaceOrientation: the view controller in which the
//              auto-truncation is incorrectly occurring for systemVersion < 6.0
//
// 2) when a view initially loads running iOS 6 for a non-0.0 value for the UITextAttributeFont
//    in the titleTextAttributes dictionary
//    solution: perform [self.navigationController.navigationBar setNeedsLayout]
//              in viewDidLoad in the view controller in which the auto truncation is
//              incorrectly occurring for systemVersion >= 6.0

所以,对于我可以使用UITextAttributeFont的0.0值但是必须继续支持iOS5的情况,我使用解决方案(1):

#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)
        && UIDevice.currentDevice.systemVersion.floatValue < 6.0)
        [self.navigationController.navigationBar setNeedsLayout];
}
#endif

在遗留代码的几个案例中我想支持iOS 6并在视图首次出现时修复故障,而不必重新编写MyAppAppearance类方法,我为my {{设置了非0.0值1}},我发现更容易实现解决方案(2):

[UINavigationBar appearance] titleTextAttributes

- (void)viewDidLoad { [super viewDidLoad]; #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0 if (UIDevice.currentDevice.systemVersion.floatValue >= 6.0) #endif [self.navigationController.navigationBar setNeedsLayout]; // … other viewDidLoadCode 括号只是帮助提醒我,如果将来需要哪些代码最终会消失,哪些代码可能必须保留。)

更准确地看一下这里发生了什么,特别是在旋转的情况下,运行模拟器,切换动画很慢。

答案 4 :(得分:0)

即使您没有像Ben Clayton所描述的那样进行方向切换,也可能发生在通过外观应用更改后切断UINavigationBar标题文本的错误。我已经在仅支持纵向方向的应用程序上看到此问题。

[self.navigationItem setTitle:@""];
[self.navigationItem setTitle:@"The real title"];

即使在这种情况下也能正常工作。

顺便说一下,自从iOS 5以来我就遇到了这个问题。现在在iOS 6中测试它,而且还在那里测试它。怎么了,Apple?