如何自定义qlpreviewcontroller中导航栏的颜色

11

我可以在QlPreviewController控制器中自定义导航栏的颜色吗?

我尝试了以下方法:

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

但它不起作用。

谢谢。


请不要这样标记代码:`code`,而是在您的代码前面添加四个空格。另外,请解释一下什么是“不起作用”。您的系统在运行此类代码时是否会崩溃? - user6250760
5个回答

12

如果您通过presentViewController: animated:显示iOS11的QLPreviewController,则barTintColor存在错误。

我的解决方案是使用1x1图像的setBackgroundImage:而不是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)

不错的建议,通过设置图像对我有用。 - johnrechd
1
谢谢!我将其转换为Swift 4并提供了一个独立的答案。 - Tum

2

感谢Aleksander Lashevich的回答!非常好用。为了方便,我将其转换为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()!
}

2
如果您不想出于任何原因使用外观代理,则有另一种解决方法,即通过子类化QLPreviewController来解决此问题。事实证明,如果以模态方式呈现QLPreviewController,则会创建一个UINavigationController,然后将其作为子ViewController添加到视图层次结构中。但是,这并不是在初始化甚至在viewDidLoad被调用之前发生的。它发生在要呈现QLPreviewController时。所以,在QLPreviewController子类中重写 viewWillAppear函数是解决该问题的方法:
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
    }
}

0

我使用这个解决方法,因为其他所有方法对我都不起作用。

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
    }
}

这种情况下,navigationController?.navigationBar 为空,在 viewDidLoadviewWillAppear 中都是如此,没有任何影响。 - inexcii

-1
请在 App delegate 中使用以下代码:
[[UINavigationBar appearance] setBarTintColor:#你的颜色#];

在AppDelegate.m文件中 - Ashish vani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接