Пользовательский фон под прозрачной панелью UINavigationBar

StackOverflow https://stackoverflow.com/questions/2219961

Вопрос

Существует пользовательский UIImageView под "Черной полупрозрачной" панелью UINavigationBar, но я не слишком доволен результатом.Пользовательское изображение недостаточно заметно, и хотя изменение альфа-значения панели навигации делает его более заметным, заголовок панели навигации и кнопки становятся менее заметными.

Вопрос: Мне нужно полностью видимое пользовательское фоновое изображение UINavigationBar с полностью видимым заголовком панели и кнопками.Есть какие-нибудь идеи, как бы мне получить все это?

Обновить: Мое решение было похоже на эти ответы, но немного отличалось.Не хочу принимать свой собственный ответ как правильный, поэтому написал об этом в блоге (Ссылка) у Илессонов я учился.

Это было полезно?

Решение

Вы также можете создать класс категории UINavigationBar и переопределить drawLayer:inContext: метод.Внутри drawLayer:inContext: метод, вы можете нарисовать фоновое изображение, которое хотите использовать.

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
    if ([self isMemberOfClass:[UINavigationBar class]] == NO) {
        return;
    }

    UIImage *image = (self.frame.size.width > 320) ?
                        [UINavigationBar bgImageLandscape] : [UINavigationBar bgImagePortrait];
    CGContextClip(context);
    CGContextTranslateCTM(context, 0, image.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), image.CGImage);
}

Полный демонстрационный проект Xcode по настройке внешнего вида UINavigationBar. этот и этот может быть полезно.

Другие советы

Мне тоже нужно было пользовательское фоновое изображение UINavigationBar, и в итоге я решил это с помощью:

  • При инициализации UINavigationController я создал CALayer, который имел contents установите фоновое изображение и рамку соответственно.
  • Я добавил этот слой к слою UINavigationBar (с индексом 0, в фоновом режиме): [self.navigationBar.layer insertSublayer:imageLayer atIndex:0]

На данный момент все выглядит нормально, но если вы выполните какую-либо навигацию, надписи и кнопки исчезнут за "фоновым" слоем.Итак,

  • Я создал подкласс CALayer, который изменил поведение insertSublayer:atIndex:таким образом, чтобы никакие слои не были вставлены под фоновый слой.

Вот так:

 @implementation CTNavigationBarLayer 
 - (void)insertSublayer:(CALayer *)layer atIndex:(unsigned)idx {
     if ( idx == 0 ) idx = 1;
     [super insertSublayer:layer atIndex:idx];
 }
 - (void)addBackgroundLayer:(CALayer*)layer {
     [super insertSublayer:layer atIndex:0];
 }
 @end
  • Используя категорию в UINavigationBar, я перегрузил +layerClass способ возврата [CTNavigationBar class], таким образом, панель навигации использует пользовательский слой.

Конечно, это меняет поведение ВСЕ UINavigationBars в вашем приложении, поэтому, если это не то, что вы хотите, вам следует поискать альтернативный способ.Вы могли бы создать подкласс UINavigationBar, но тогда единственный способ заставить этот подкласс использоваться в UINavigationController - это использовать IB (или сделать что-нибудь довольно интересное валять дурака чтобы сделать это программно)

  • Наконец, вернувшись к инициализации UINavigationController, я заменил вставку слоя вызовом addBackgroundLayer: метод, который я написал.

Использование drawRect в категории для UINavigationBar не будет работать в iOS5.Apple предлагает создать подкласс UINavigationBar и использовать его в своем NIB-файле.

Для удобства тех, кто придет сюда чуть позже, стоит отметить, что iOS5 обеспечивает прямую поддержку такого рода настройки.Чтобы изменить изображение, лежащее в основе UINavigationBar, используйте

- (void)setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics

Еще есть недвижимость

@property(nonatomic, copy) NSDictionary *titleTextAttributes

для корректировки названия.И вы можете использовать прокси внешнего вида, чтобы эти изменения распространились на ваше приложение.Больше обсуждения на WWDC 2011, сессия 114, «Настройка внешнего вида элементов управления UIKit».

До iOS5 предполагалось, что это будет создание подкласса UINavigationBar.

Решение ardalahmet не является правильным, если вам нужны разные фоны для каждого UINavigationBar, когда у вас есть более одного UINavigationController, например, в UITabBar, поскольку он использует категории UINavigationBar.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top