Изменение фонового изображения UINavigationBar в ios <5 - PullRequest
2 голосов
/ 20 января 2012

У меня проблема с изменением фонового изображения UINavigationBar для версии IOS <5. Я уже читал об одном хорошем решении, основанном на методе Swizzling, но проблема этого решения заключается в том, когда я добавляю изображение это охватывает все, включая кнопки на панели навигации. Я нашел решение, которое частично сработало для меня, оно основано на следующем коде: </p>

@interface UINavigationBar (UINavigationBarCategory)
-(void)setBackgroundImage:(UIImage*)image withTag:(NSInteger)bgTag;
-(void)resetBackground:(NSInteger)bgTag; 
@end

@implementation UINavigationBar (UINavigationBarCategory)

-(void)setBackgroundImage:(UIImage*)image withTag:(NSInteger)bgTag{
if(image == NULL){ //might be called with NULL argument
    return;
}
UIImageView *aTabBarBackground = [[UIImageView alloc]initWithImage:image];
aTabBarBackground.frame = CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
aTabBarBackground.tag = bgTag;
[self addSubview:aTabBarBackground];
//[self sendSubviewToBack:aTabBarBackground];
[aTabBarBackground release];
}
-(void)setRightButton:(UIButton*)button withTag:(NSInteger)bgTag{
if(button == NULL){ //might be called with NULL argument
    return;
}
    [self addSubview:button];
}

/* input: The tag you chose to identify the view */
-(void)resetBackground:(NSInteger)bgTag {
[self sendSubviewToBack:[self viewWithTag:bgTag]];
}
@end

Я использовал эту категорию в моих ViewWillAppear методах, подобных этому:

-(void) viewWillAppear:(BOOL)animated {
 UIImage *backgroundImage = [UIImage imageNamed:@"background_confernce_import_logo"];

if ([self.navigationController.navigationBar  respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)])
{
    [self.navigationController.navigationBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
}
else{

   [[self.navigationController navigationBar] setBackgroundImage:backgroundImage     withTag:8675309];
}
}

В другом предложении я называю setBackgroundImage. Это нормально, но проблема в том, что если у меня есть правая кнопка на панели навигации, например, на странице 1, и я вернусь на страницу 2 после того, как вернусь на страницу 1, кнопка исчезнет. Я должен изменить фоновое изображение панели навигации на каждой странице в моем приложении, например, в методе viewWillAppear, где я помещаю новое изображение. Любая помощь будет оценена. Под IOS 5 такой проблемы нет, но она должна работать на обеих версиях.

Ответы [ 2 ]

1 голос
/ 20 января 2012

Мне неприятно это говорить, но ваш подход (добавление подпредставления для хранения фона) не будет работать именно по той причине, которую вы упомянули. Каждый раз, когда панель навигации перерисовывается, подпредставление не будет сохранять свой z-порядок (и, следовательно, оно будет охватывать другие элементы пользовательского интерфейса). Это поведение описывается другими источниками (см. this , например)

Если вы не хотите использовать Swizzling, вы можете переопределить drawRect в категории, чтобы фон всегда отображался правильно. (у этого последнего варианта есть недостаток, что любая панель навигации в вашем приложении будет нарисована с тем же фоном). Это пример кода, который я использую:

@implementation UINavigationBar (CustomBackground)

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

Другой подход может быть:

  1. Подклассы UINavigationBar;
  2. переопределение drawRect;
  3. в Интерфейсном Разработчике, установите класс вашего объекта панели навигации на ваш UINavigationBar подкласс.

Я не пробовал, но оно должно работать.

0 голосов
/ 20 января 2012

В соответствии с запросом, здесь идет мой слегка непослушный и не очень отполированный хак.Это действительно просто для того, чтобы осчастливить OP.Правильный ответ дал sergio.


UINavigationBar + CustomDraw.m

NSString *gNavbarBackgroundImageName = @"default_navbar_background.png";

@implementation UINavigationBar (CustomBackground)

- (void)drawRect:(CGRect)rect 
{ 
    if (gNavbarBackgroundImageName != nil)
    {
        UIImage *image = [UIImage imageNamed:gNavbarBackgroundImageName]; 
        [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    }
}
@end

UINavigationBar + CustomDraw.h

extern NSString *gNavbarBackgroundImageName;

И вот пример использования в двух контроллерах представления ...


FooViewController.m

#import "UINavigationBar+CustomDraw.h"

@implementation FooViewController

- (void)viewWillAppear:(BOOL)animated
{
    gNavbarBackgroundImageName = @"foo_navbar_background.png";
    [self.navigationController.navigationBar setNeedsDisplay];
}

@end

BarViewController.m

#import "UINavigationBar+CustomDraw.h"

@implementation BarViewController

- (void)viewWillAppear:(BOOL)animated
{
    gNavbarBackgroundImageName = @"bar_navbar_background.png";
    [self.navigationController.navigationBar setNeedsDisplay];
}

@end

Теперь давайте предположим, что вы хотите показать нестандартную панель навигации, например, при отображении страницы входа в Facebook(в соответствии с их SDK).

Используйте это, чтобы предотвратить любое пользовательское рисование:

gNavbarBackgroundImageName = nil;

Примечание Некоторые компоненты Apple используют UINavigationBar в местах, которые вы не можетедумал о.Например, MPMoviePlayerController использует настраиваемую панель навигации для отображения верхней части своего пользовательского интерфейса - так что это будет другой случай, когда вы хотите запретить пользовательское рисование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...