Пользовательский фон под прозрачным UINavigationBar - PullRequest
1 голос
/ 08 февраля 2010

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

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

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

Ответы [ 5 ]

3 голосов
/ 21 июня 2010

Я тоже хотел создать собственное фоновое изображение UINavigationBar, и в итоге решил его:

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

На данный момент все выглядит хорошо, но если вы выполняете какую-либо навигацию, метки и кнопки исчезают за слоем 'background'. Таким образом,

  • Я создал подкласс 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:, который я написал.
2 голосов
/ 26 января 2012

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

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

Там также есть свойство

@property(nonatomic, copy) NSDictionary *titleTextAttributes

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

До выхода iOS5 то, что вы должны были сделать, заключалось в создании подкласса UINavigationBar.

2 голосов
/ 21 сентября 2011

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

1 голос
/ 13 февраля 2011

Вы также можете создать класс категории 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 это и это может быть полезно.

0 голосов
/ 10 июня 2011

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

...