Ответ 1
Итак, это старый вопрос, но я наткнулся на него, когда искал что-то похожее на этот вопрос, но он другой. В надежде, что это поможет кому-то другому (или что кто-то еще покажет мне лучший способ)...
Как реализовать пользовательский градиент на 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, который должен быть легким ya? Просто добавьте его как подуровень, не так ли? Проблема здесь в том, что он скроет прекрасные кнопки и прочее, что дает вам UINavigationController. Это плохо.
Вместо этого взгляните на замечательный метод удобства, который у нас есть в iOS5 +, чтобы изменить внешний вид всех UINavigationBar (ов) в нашем приложении:
[[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
- Мне не нужно зависеть от реального ресурса изображения/легко обновлять
Но я все еще не убежден, что это лучший способ. Поэтому, наслаждайтесь, если это поможет вам, дайте мне знать, как улучшить его, если сможете.
~ Спасибо