UINavigationBar + UIToolBar UIAppearance, а также полупрозрачный barStyle в некоторых частях приложения?

Я устанавливаю пользовательские изображения для своих UINavigationBar и UIToolbar, используя следующий код:

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navigationBar"] forBarMetrics:UIBarMetricsDefault];
[[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed:@"toolbar"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];

Я использую PhotoViewer и выдвигаю его контроллер представления в поле зрения. Он должен иметь полупрозрачную панель навигации и панель инструментов, но вместо этого он использует графику, которую я поставил с полупрозрачностью.

Проблема в том, что позже, когда я нажимаю другой контроллер представления (после возврата к super из PhotoViewer), его панель инструментов также становится полупрозрачной, что означает, что содержимое находится за ней.

Я пробовал следующее без везения:

[[UINavigationBar appearanceWhenContainedIn:[EGOPhotoViewController class], nil] setBarStyle:UIBarStyleBlackTranslucent];
[[UINavigationBar appearanceWhenContainedIn:[EGOPhotoViewController class], nil] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[[UIToolbar appearanceWhenContainedIn:[EGOPhotoViewController class], nil] setBarStyle:UIBarStyleBlackTranslucent];
[[UIToolbar appearanceWhenContainedIn:[EGOPhotoViewController class], nil] setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];

Любые идеи, как я могу получить черный полупрозрачный barStyle только для PhotoViewer и сохранить все остальное с моей пользовательской графикой?

ОБНОВЛЕНИЕ: в попытке получить помощь я собрал пример проекта с пользовательской графикой для панели навигации, а затем безуспешно пытался отобразить нажатый контроллер представления с полупрозрачной панелью навигации, когда с использованием прокси внешнего вида: ПРОЕКТ ПРИМЕРА


person runmad    schedule 27.08.2012    source источник


Ответы (2)


Я скачал ваш образец проекта и смог его исправить. Я объясню, в чем проблема.

Прежде всего, UINavigationBar содержится внутри UINavigationController. Итак, RootViewController и TranslucentViewController используют один и тот же экземпляр UINavigationBar. Возможно, это вызывает путаницу. Кроме того, вероятно, поэтому +appearanceWhenContainedIn: работает не так, как вы ожидаете.

Чтобы установить фоновое изображение для панелей навигации во всем приложении, вы должны использовать +appearance. Чтобы установить фоновое изображение одной панели навигации в контроллере навигации, используйте -setBackgroundImagE:forBarMetrics: UINavigationBar.

Код: в -TranslucentViewController viewWillAppear: установите фоновое изображение и стиль панели. В RootViewController снова установите фоновое изображение и стиль панели. По моему опыту, лучше всего изменить панель навигации в -viewWillAppear: вместо -in viewWillDisappear: (или вам нужно отслеживать, на что ее изменить).

В рутвиевконтроллере

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"orangeNavigationBar.png"] forBarMetrics:UIBarMetricsDefault];
}

В TranslucentViewController

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

    [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setBarStyle:UIBarStyleBlackTranslucent];
}

Да и еще: менять только в этих местах. Не при нажатии на контроллер представления или что-то еще.

person martijndeh    schedule 18.09.2012

В зависимости от того, используете ли вы панель вкладок или нет, вы можете назначить свой appDelegate делегатом панели навигации или подклассом UINavigationController, чтобы ваш код знал обо всех изменениях в стеке viewController. Затем вы устанавливаете свойство UINavigationBar, чтобы сделать его прозрачным или непрозрачным в зависимости от класса видимого viewController.

person David H    schedule 27.08.2012
comment
К сожалению, я использую UITabBarController. - person runmad; 27.08.2012
comment
Что ж, не все так плохо. TabBarController становится делегатом баров UINavigation, и вы не можете это изменить. Но вы можете создать подкласс UINavigation bar (я сделал это по разным причинам) и добавить методы (которые также вызывают super!), чтобы перехватывать изменения в viewControllers. Это не так сложно, и вы можете установить прозрачность tabBarController по своему усмотрению, поскольку каждый viewController является просматриваемым в данный момент. - person David H; 27.08.2012
comment
Я думал, что UIAppearance как-нибудь справится с этим? Я имею в виду, что Apple, похоже, отлично справляется с Music.app. - person runmad; 27.08.2012
comment
Почему вы предполагаете, что они достигают этого результата с помощью UIAppearance? Если проблема возникает ТОЛЬКО, когда вы возвращаетесь после нажатия PhotoViewer, установите флаг, а когда вы получите сообщение viewWillAppear, посмотрите на флаг и установите прозрачность панели навигации. Или просто отметьте его везде в viewWillAppear и установите как хотите. - person David H; 28.08.2012
comment
Я проверил код, и он возвращается к исходному стилю на viewWillDisappear в контроллере представления PhotoViewer. Я также пытался установить его по умолчанию на контроллере суперпредставления, а также на контроллере представления, который я нажимаю после PhotoViewer, и это не работает. Кроме того, я даже не вижу черный полупрозрачный стиль по умолчанию, а вместо этого мою собственную графику для панели навигации и панели инструментов с некоторой прозрачностью - это не тот эффект, который я ищу. - person runmad; 28.08.2012