Как установить изображение в качестве фона панели навигации без использования категории drawRect?

Я хочу установить фоновое изображение для панели навигации в моем приложении для iphone. Большинство решений предлагают использовать drawRect в таких категориях, как:

@implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"NavigationBar.png"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end

Однако Apple этого не рекомендует. Любое другое предложение?

Спасибо за помощь,

Стефан


person Steve    schedule 08.09.2011    source источник


Ответы (3)


Apple настоятельно рекомендует нам использовать подклассы, а не категории (WWDC 2011, сессия 123).

Создайте подкласс, который реализует метод drawRect:, и установите класс панели навигации на свой собственный класс:

  • если вы работаете в Interface Builder, измените класс в инспекторе
  • если вы создаете автономную панель навигации (без контроллера навигации), создайте экземпляр своего пользовательского класса
  • если вы создаете контроллер навигации программно, вы можете воспользоваться преимуществами среды выполнения ObjC.

Переключение класса во время выполнения:

 #import <objc/runtime.h>
 ...
 object_setClass(theNavController.navigationBar, [CustomNavigationBar class]);

Вам также следует избегать использования [UIImage imageNamed:...] каждый раз в drawRect:, поскольку это может повлиять на производительность (для анимации). Кешируйте его в ivar:

 if (!bgImage) {
     bgImage = [[UIImage imageNamed:@"NavigationBar.png"] retain];
 }
 [bgImage drawInRect:...];

(и отпустите его в dealloc)

Примечание. Поскольку iOS 5 все еще находится под соглашением о неразглашении, я не могу упомянуть, как можно легко добавить фоновое изображение. Ознакомьтесь с документацией для UINavigationBar.

person Jilouc    schedule 08.09.2011
comment
новый API iOS5 не масштабирует изображение. :-( - person Teo Choong Ping; 16.09.2011
comment
@Seymour Да, я тоже это заметил. Вместо этого я использовал изображение 320 * 44. Я, вероятно, подам запрос функции. - person Jilouc; 16.09.2011
comment
вы можете изменить размер UIImage до размера navigationBar перед его настройкой - для меня это хорошо работает - person Teo Choong Ping; 16.09.2011

Протестированный код: 100% работает

в ur ViewDidLoad

UIImageView *iv=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"urNavBarImage.png"]];

self.navigationItem.titleView = iv;

[iv release];

ПРИМЕЧАНИЕ. urNavBarImage должен соответствовать размеру панели навигации. Таким образом вы можете изменить каждую панель навигации Viewcontroller.

person Vijay-Apple-Dev.blogspot.com    schedule 08.09.2011

Я создал настраиваемую категорию для UINavigationBar следующим образом

UINavigationBar+CustomImage.h

#import <UIKit/UIKit.h>

@interface UINavigationBar (CustomImage)
    - (void) setBackgroundImage:(UIImage*)image;
    - (void) clearBackgroundImage;
    - (void) removeIfImage:(id)sender;
@end

UINavigationBar+CustomImage.m

#import "UINavigationBar+CustomImage.h"

@implementation UINavigationBar (CustomImage)

- (void) setBackgroundImage:(UIImage*)image {
    if (image == NULL) return;
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = CGRectMake(110,5,100,30);
    [self addSubview:imageView];
    [imageView release];
}

- (void) clearBackgroundImage {
    NSArray *subviews = [self subviews];
    for (int i=0; i<[subviews count]; i++) {
        if ([[subviews objectAtIndex:i]  isMemberOfClass:[UIImageView class]]) {
        [[subviews objectAtIndex:i] removeFromSuperview];
    }
   }    
}

@end

Я вызываю его из своего UINavigationController

[[navController navigationBar] performSelectorInBackground:@selector(setBackgroundImage:) withObject:image];
person Nikunj Jadav    schedule 08.09.2011