Как настроить цвет панели навигации в qlpreviewcontroller

Можно ли настроить цвет панели навигации в контроллере QlPreviewController?

Я пробовал следовать

[[UINavigationBar appearanceWhenContainedIn: [QLPreviewController class], nil] setBarTintColor: [UIColor redColor]];

Но это не работает.

Спасибо.


person user2843506    schedule 15.09.2017    source источник
comment
Пожалуйста, не помечайте код так: `код`, вместо этого добавьте четыре пробела перед своим кодом. Также, пожалуйста, объясните, что такое «не работает». Ваша система взрывается при запуске такого кода?   -  person    schedule 15.09.2017


Ответы (5)


Да, есть ошибка с 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)
person Aleksander Lashevich    schedule 02.11.2017
comment
Хорошее предложение, сработало для меня, установив изображение. - person johnrechd; 04.11.2017
comment
Спасибо! Я преобразовал его в Swift 4 в отдельном ответе. - person Tum; 25.09.2018

Спасибо Александру Лашевичу за ответ! Работает как шарм. Я преобразовал его в 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()!
}
person Tum    schedule 25.09.2018

Если вы, ребята, по какой-либо причине не хотите использовать прокси внешнего вида, есть другой способ решить эту проблему, если вы создадите подкласс 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
    }
}
person Milutin Tomic    schedule 24.06.2019

Я использую этот обходной путь, потому что все остальные мне не подходят.

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
    }
}
person ChikabuZ    schedule 01.10.2020

Пожалуйста, используйте приведенный ниже код в делегате приложения

[[Внешний вид UINavigationBar] setBarTintColor:#ваш цвет#];

person Ashish vani    schedule 15.09.2017
comment
*в AppDelegate.m - person Ashish vani; 15.09.2017