Подтвердить что ты не робот

Настроить шрифт 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, вы получите проблему с заголовком панели навигации после поворота от портрета к пейзажу, а затем назад к портрету.

4b9b3361

Ответ 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?