Можно ли настроить цвет панели навигации в контроллере QlPreviewController?
Я пробовал следовать
[[UINavigationBar appearanceWhenContainedIn: [QLPreviewController class], nil] setBarTintColor: [UIColor redColor]];
Но это не работает.
Спасибо.
Можно ли настроить цвет панели навигации в контроллере QlPreviewController?
Я пробовал следовать
[[UINavigationBar appearanceWhenContainedIn: [QLPreviewController class], nil] setBarTintColor: [UIColor redColor]];
Но это не работает.
Спасибо.
Да, есть ошибка с barTintColor в QLPreviewController для iOS 11, если вы показываете его через presentViewController: animated:
Вот мое решение: используйте setBackgroundImage: с изображением 1x1 вместо setBarTintColor:
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[QLPreviewController class]]]
setBackgroundImage:[UIImage imageWithColor:[UIColor redColor]]
forBarMetrics:UIBarMetricsDefault];
И imageWithColor: — это метод в моей пользовательской категории UIImage, который возвращает изменяемое по размеру изображение 1x1 желаемого цвета (красный цвет в приведенном выше примере):
+ (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
const CGFloat alpha = CGColorGetAlpha(color.CGColor);
const BOOL opaque = alpha == 1;
UIGraphicsBeginImageContextWithOptions(rect.size, opaque, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Я также предлагаю обернуть это проверкой версии iOS, например:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) {
[[UINavigationBar appearance...
setBackgroundImage:[UIImage imageWithColor:...]
forBarMetrics:UIBarMetricsDefault];
}
Откуда SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO
:
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
Спасибо Александру Лашевичу за ответ! Работает как шарм. Я преобразовал его в Swift 4 для удобства.
let navbar = UINavigationBar.appearance(whenContainedInInstancesOf: [QLPreviewController.self])
navbar.setBackgroundImage(self.imageWithColor(color: UIColor.red), for: UIBarMetrics.default)
И для генерации изображения:
func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
let alpha = color.cgColor.alpha
let opaque = alpha == 1
UIGraphicsBeginImageContextWithOptions(rect.size, opaque, 0)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(color.cgColor)
context?.fill(rect)
return UIGraphicsGetImageFromCurrentImageContext()!
}
Если вы, ребята, по какой-либо причине не хотите использовать прокси внешнего вида, есть другой способ решить эту проблему, если вы создадите подкласс QLPreviewController. Оказывается, если вы представляете QLPreviewController модально, он создает UINavigationController, который затем добавляется как дочерний ViewController в иерархию представлений. Однако этого не происходит при инициализации или даже до вызова viewDidLoad. Это происходит, когда должен быть представлен QLPreviewController. Таким образом, переопределение функции viewWillAppear в подклассе QLPreviewController — это правильный путь:
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let nc = self.children.first as? UINavigationController {
// your customization code goes here
nc.navigationBar.tintColor = .yellow
}
}
Я использую этот обходной путь, потому что все остальные мне не подходят.
import QuickLook
class PreviewController: QLPreviewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.setBackgroundImage(nil, for: .any, barMetrics: .default)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.isTranslucent = false //optional
}
}
Пожалуйста, используйте приведенный ниже код в делегате приложения
[[Внешний вид UINavigationBar] setBarTintColor:#ваш цвет#];