Так что это старый вопрос, но я наткнулся на него, когда искал что-то похожее на этот вопрос, но другое. В надежде, что это поможет кому-то другому (или что кто-то другой покажет мне лучший путь) ...
Как реализовать пользовательский градиент на панели UINavigationBar?
Во-первых, давайте получим наш собственный градиент, как обычно (как CALayer):
- (CALayer *)gradientBGLayerForBounds:(CGRect)bounds
{
CAGradientLayer * gradientBG = [CAGradientLayer layer];
gradientBG.frame = bounds;
gradientBG.colors = @[ (id)[[UIColor redColor] CGColor], (id)[[UIColor purpleColor] CGColor] ];
return gradientBG;
}
Итак, градиент, который выглядит как сомнительный выбор грима панк-рокера, и это хорошо, так как этот код предназначен для гипотетического приложения У меня есть панк-рокер с сомнительными вкусами в моем кармане . Это имя меня будет слишком длинным ..
Теперь я хочу этот слой на моей UINavigationBar, который должен быть легким, да? Просто добавьте его как подслой, верно? Проблема здесь в том, что он закроет замечательные кнопки и все, что дает вам UINavigationController. Это плохо.
Вместо этого давайте рассмотрим замечательный удобный метод, который мы используем в iOS5 + для изменения внешнего вида всех UINavigationBar (s) в нашем приложении:
[[UINavigationBar appearance] setBackgroundImage:SOME_IMAGE
forBarMetrics:UIBarMetricsDefault];
Единственная проблема здесь в том, что у нас нет UIImage, у нас есть CALayer. Что делать энтузиасту панк-рокера?
CALayer * bgGradientLayer = [self gradientBGLayerForBounds:ONE_OF_YOUR_NAV_CONTROLLERS.navigationBar.bounds];
UIGraphicsBeginImageContext(bgGradientLayer.bounds.size);
[bgGradientLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * bgAsImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Итак, теперь мы преобразовали наш CALayer в UIImage (надеюсь), поэтому осталось только установить его:
if (bgAsImage != nil)
{
[[UINavigationBar appearance] setBackgroundImage:bgAsImage
forBarMetrics:UIBarMetricsDefault];
}
else
{
NSLog(@"Failded to create gradient bg image, user will see standard tint color gradient.");
}
Что мне нравится в этом решении
- централизованный код (в AppDelegate) для всех UINavigationBar (s) в моем приложении
- tintColor будет по-прежнему учитываться для всех кнопок UINavigation (назад, редактировать и т. Д.)
- если создание UIImage завершится неудачно, мои UINavigationBar (s) по-прежнему будут учитывать tintColor
- Мне не нужно зависеть от фактического ресурса изображения / его легко обновить
Но я все еще не уверен, что это лучший способ. Итак, наслаждайтесь, если это поможет вам, дайте мне знать, как улучшить его, если можете.
~ Спасибо