【问题标题】:How to customize the color of the navigation bar in qlpreviewcontroller如何在 qlpreviewcontroller 中自定义导航栏的颜色
【发布时间】:2017-09-15 12:31:15
【问题描述】:

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

我已尝试关注

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

但它不起作用。

谢谢。

【问题讨论】:

  • 请不要将代码标记为:`code`,而是在代码前添加四个空格。另请解释什么是“不起作用”。你的系统在运行这样的代码时会爆炸吗?

标签: navigationbar ios11 navigationcontroller qlpreviewcontroller bartintcolor


【解决方案1】:

是的,如果您通过presentViewController: animated: 显示它,那么 iOS 11 的 QLPreviewController 上的 barTintColor 存在一个错误

这是我的解决方案,将 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。
【解决方案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()!
}

【讨论】:

    【解决方案3】:

    如果你们出于某种原因不想使用外观代理,如果您将 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
        }
    }
    

    【讨论】:

      【解决方案4】:

      我使用此解决方法是因为所有其他方法都不适合我。

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

      【讨论】:

        【解决方案5】:

        请在应用委托中使用以下代码

        [[UINavigationBar 外观] setBarTintColor:#your color#];

        【讨论】:

        • *在 AppDelegate.m 中
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        • 2013-12-21
        • 2011-12-05
        • 1970-01-01
        • 2011-07-31
        • 1970-01-01
        相关资源
        最近更新 更多