Настроить шрифт UINavigationBar
Я пытаюсь настроить свой шрифт UINavigationBar, используя следующий код для iOS 5 в своем делетете приложения application:didFinishLaunchingWithOptions
:
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]];
}
Он отлично работает, и панель навигации отображается с помощью моего шрифта. Отлично.
ссылки. Я нашел, что вы можете использовать размер шрифта равным нулю, и он изменит размер шрифта в соответствии с вашей навигационной панелью (используя немного меньший шрифт для более короткой панели навигации для ландшафтного макета). И он выбирает размер шрифта, который прекрасно подходит к высоте панели навигации. Но похоже, что если вы переходите от портрета к пейзажу и обратно, ширина ярлыка заголовка навигационной панели закручивается, поэтому то, что отображается как заголовок, например, "Long Titlebar", отлично выглядит при первом просмотре в портретной ориентации выглядит отлично, когда вы просматриваете его в ландшафте (с соответствующим меньшим шрифтом), но когда я возвращаюсь к портрету, шрифт правильно возвращается к более крупному шрифту, но сам текст заголовка усекается, становясь "Long..." хотя есть достаточно места для полного титула. Кто-нибудь еще видел это поведение при использовании размера шрифта 0.0?
Ясно, что я могу просто указать фактический размер шрифта (в этом случае я не вижу этого усекающего поведения), но потом я вручную выясню, какой размер использовать. И что еще хуже, размер шрифта одинаковый для пейзажа и портрета, поэтому прямо сейчас я использую размер шрифта, который подходит для более короткого заголовка ландшафтной навигации, а название меньше, чем должно быть в верхней панели навигации на портрете.
У кого-нибудь есть опыт использования setTitleTextAttributes
для изменения шрифта [UINavigationBar appearance]
таким образом, чтобы размер шрифта изменялся между портретом и ландшафтом, но не имел этого усечения заголовка, когда вы возвращаетесь обратно портрет после перехода в пейзаж? Я собираюсь заниматься различными обходными решениями, но если у вас есть какой-либо опыт в этой проблеме, сообщите мне.
Update:
В процессе отправки этой ошибки Apple я решил продемонстрировать, как воспроизвести проблему:
-
Создайте новое приложение Master-Detail iOS в Xcode 4.3.2.
-
Поместите вышеуказанный код setTitleTextAttributes
в делегат приложения application:didFinishLaunchingWithOptions
(я использовал шрифт @ "GillSans" ).
-
Перейдите в MasterViewController и добавьте строку, которая говорит self.title = @"Long Title";
-
Прокомментируйте код UIBarButtonItem *addButton
.
-
Запустите программу. Обратите внимание, что заголовок правильно говорит "Long Title". Поворот к пейзажу. Все еще выглядит хорошо. Повернитесь назад к портрету, и название теперь говорит "Long...", хотя там много места.
-
Любопытно, что если вы восстановите код UIBarButtonItem *addButton
, заголовок будет работать так, как должен. Но если вы либо исключите элемент UIBarButton, либо замените его кнопкой, которая использует initWithTitle
, а не initWithBarButtonSystemItem
, вы получите проблему с заголовком панели навигации после поворота от портрета к пейзажу, а затем назад к портрету.
Ответы
Ответ 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 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
поэтому для случаев, когда я в порядке с использованием значения 0.0 для UITextAttributeFont
, но мне нужно продолжать поддерживать 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, у меня есть значения, отличные от 0 для моего [UINavigationBar appearance] titleTextAttributes
, мне было проще реализовать решение (2), таким образом:
- (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
(и скобка __IPHONE_OS_VERSION_MIN_REQUIRED
просто помогает мне напоминать, какой код в конечном итоге может исчезнуть, если это необходимо в будущем, и что, возможно, придется остановиться.)
чтобы увидеть более точно то, что здесь происходит, особенно в случае вращения, запустить симулятор с медленными анимациями.
Ответ 2
Кстати, я пренебрег тем, что Apple ответила на мой отчет об ошибке, признав, что это была известная проблема. Надеюсь, скоро это будет решено!
Ответ 3
Я думаю, что хорошим решением является обновление заголовка вашего Navbar после поворота устройства. Что-то вроде
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
self.navigationItem.title = @"Your title";
}
Надеюсь, это поможет!
Ответ 4
Основываясь на ответе от @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";
}
Ответ 5
Ошибка, при которой текст заголовка UINavigationBar отключается после внесения изменений через внешний вид, может произойти, даже если вы не выполняете ориентационное переключение, как описывает Бен Клейтон. Я видел, что эта проблема возникает в приложении, которое поддерживает ориентацию только по книгам.
[self.navigationItem setTitle:@""];
[self.navigationItem setTitle:@"The real title"];
Будет работать нормально даже в таком случае.
Кстати, у меня была эта проблема с iOS 5. Просто протестировал ее прямо сейчас в iOS 6 и IT STILL THERE. Что за черт, Apple?