Пользовательский фон UINavigationBar - PullRequest
50 голосов
/ 01 апреля 2009

Я пытался настроить пользовательский фон для всего моего NavigationBar (не только titleView), но изо всех сил.

Я нашел эту тему

http://discussions.apple.com/thread.jspa?threadID=1649012&tstart=0

Но я не уверен, как реализовать данный фрагмент кода. Код реализован как новый класс? Также, где я могу установить UINavigationController, так как у меня есть приложение, созданное с помощью шаблона NavigationView, чтобы оно не выполнялось в моем корневом контроллере, как в примере

Ответы [ 15 ]

2 голосов
/ 14 апреля 2011

Ваша проблема в том, что если вы используете контроллер навигации, заголовок каждой страницы будет перекрывать вашу пользовательскую панель навигации. Если ваша навигационная панель содержит логотип или название вашего приложения, это явно недопустимо.

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

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

    YourAppDelegate* theApp = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
    UIImage* image = [UIImage imageNamed:theApp.navBarName];

Затем в первом контроллере представления, который вы поместите в стек навигации, сделайте что-то вроде этого:

- (void)viewWillAppear:(BOOL)animated
{
    YourAppDelegate* theApp = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
    theApp.navBarName = @"navBar_plain";
}

Затем в контроллере корневого представления сделайте то же самое, но укажите свое изображение логотипа с логотипом, которое будет восстановлено, когда пользователь вернется к нему без конфликтующего заголовка.

1 голос
/ 01 апреля 2012

Как уже говорила сама Apple, некорректно переопределять методы в категориях. Поэтому лучший способ настроить фон UINavigarionBar - это создать подклассы и переопределить метод -(void)drawInRect:.

@implementation AppNavigationBar
- (void)drawRect:(CGRect)rect
{
    UIImage *patternImage = [UIImage imageNamed:@"image_name.png"];
    [patternImage drawInRect:rect];
}

Чтобы использовать этот настроенный UINavigationBar, он должен быть установлен как navigationBar свойство вашего UINavigationBarController. Как вы знаете, это свойство только для чтения. Итак, что нужно сделать, это:

- (void)viewDidLoad
{
    [super viewDidLoad];

    AppNavigationBar *nav = [AppNavigationBar new];
    [self setValue:nav forKey:@"navigationBar"];
}

Работает как для iOS 5, так и для 4.3.

1 голос
/ 30 сентября 2011

Вот альтернативное решение, которое позволяет вам использовать ваш собственный подкласс UINavigationBar:

https://gist.github.com/1253807

0 голосов
/ 20 февраля 2013

Для статического вида (без анимации вообще) я использую iOS по умолчанию setBackgroundImage

Но когда у меня есть анимированное представление (скорее всего, изменение размера), я создаю пользовательский UIImageView и добавляю его в панель навигации, чтобы у меня было больше гибкости над ним

Дело в том, что если вы просто добавите его, он попадет поверх кнопок и titleView, поэтому я вручную сохраняю копию большинства подпредставлений, удаляю их из родительского представления, добавляю свой imageView и затем добавляю все подпредставления назад

Это работает для меня

    UIImageView *navBackground = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"navigationBackgroundSample.jpg"]];
    UIView *tempTitleView = [[self.navigationBar.subviews objectAtIndex:1] autorelease];
    [[self.navigationBar.subviews objectAtIndex:1] removeFromSuperview];
    [self.navigationBar addSubview:navBackground];
    [self.navigationBar addSubview:tempTitleView];
    self.navigationBar.clipsToBounds = YES;
    [navBackground release];

В этом случае у меня нет кнопок, и я обнаружил, что мой titleView имеет индекс 1, если у вас есть кнопки, они должны быть где-то в массиве subviews навигационной панели

Я не знаю, что находится в индексе 0, я не знаю, может ли это сработать, если у вас нет текстового заголовка ...

0 голосов
/ 13 августа 2012

Вы можете создать подкласс UINavigationBar и включить его следующим образом, поскольку категории для drawRect больше не будут работать в iOS5

    navigationController = [[((^ {
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:[NSKeyedArchiver archivedDataWithRootObject:navigationController]];
    [unarchiver setClass:[SAPHUINavigationBar class] forClassName:@"UINavigationBar"];
    [unarchiver setClass:[UIViewController class] forClassName:NSStringFromClass([navigationController.topViewController class])];
    return unarchiver;
})()) decodeObjectForKey:@"root"] initWithRootViewController:navigationController.topViewController];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...