【问题标题】:UIView's shadowpath color doesn't changeUIView 的 shadowpath 颜色不会改变
【发布时间】:2020-01-25 07:27:39
【问题描述】:

我有一个UIView,我为它设置了一个shadowPath,如下所示:

func addShadow() {
    let cornerRadius: CGFloat = self.containerView.frame.height/2
    self.containerView.layer.shadowPath = UIBezierPath(roundedRect: self.containerView.frame, cornerRadius: cornerRadius).cgPath
    self.containerView.layer.shadowRadius = cornerRadius
    self.containerView.layer.shadowOffset = .zero
    self.containerView.layer.shadowOpacity = 0.2
    self.containerView.layer.cornerRadius = cornerRadius
    self.containerView.layer.shadowColor = UIColor(named: "whiteColor")?.cgColor
}

这是whiteColor

现在我的问题是

当我改变手机的外观时,shadowPath 的颜色不会自动改变。我应该怎么做才能使颜色动态?

【问题讨论】:

  • 在 layoutSubview 或 viewDidLayoutSubviews 中做所有的颜色工作。然后将颜色设置为一个动态变量,该变量将根据 traitCollection.userInterfaceStyle 计算它的值
  • @andromedainiative 你确定这是最好的方法吗?我有很多视图有阴影,将它们都设置在layoutSubView中是否正确?
  • 我的意思是我所知道的没有灵丹妙药的通用解决方案。我们最终将所有颜色设置都移到了这些方法中。你可以在这里读更多关于它的内容。除非您在每个视图中使用相同的视图控制器,否则您将不得不手动更新颜色。 developer.apple.com/documentation/appkit/…
  • @andromedainiative 很好的文档,谢谢

标签: ios swift uiview ios-darkmode shadowpath


【解决方案1】:

所有图层属性不会自动对颜色变化做出反应(由于转换为CGColor)。

相反,当颜色外观发生变化时,对特征集合的变化做出反应并重新设置属性:

override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    if #available(iOS 13, *), self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
        // re-set your properties here
    }
}

【讨论】:

  • 那么我应该在每个ViewController?!我需要一个更通用的解决方案!
  • 只有您设置了图层属性。但是,是的,这是一种痛苦。我创建了一个BaseView,它为所有这些图层属性提供UIColor 属性并处理外观更改。但现在我最终得到了 4 个不同的 BaseViews 按钮、表格视图单元格等......?
  • 请调用 super.traitCollectionDidChange
【解决方案2】:

所以这对我有用 - 它是 Frank Schlegel 的答案和 Kurt Revis 的 answer to the cgColor question 之间的混合体


override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {

   if #available(iOS 13, *), self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {

       SubmissionOptionsMenu.layer.shadowColor = 
              UIColor.label.resolvedColor(with: self.traitCollection).cgColor
   }
}

【讨论】:

    【解决方案3】:

    添加 self.view.layoutIfNeeded() 在您的功能中。它可能会解决您的问题。以另一种方式,您将在viewDidLayoutSubviews 中添加颜色。

    【讨论】:

    • self.view.layoutIfNeeded() 不起作用,我认为覆盖 viewDidLayoutSubViews 不是最好的!因为我应该在每个 ViewController 中重写这个方法!我需要一个更通用的解决方案!
    • 我能想到的最好的通用解决方案是创建一个基本视图类来处理特征更改并从中派生出所有需要它的视图。
    • 你可以在主线程中运行它吗?它可能是工作。我的意思是使用 - func addShadow() { DispatchQueue.main.async { //你的代码在这里} }
    • @NahidRaihan 什么都没发生!
    • 1.从哪里调用这个函数? 2.在方法中添加self.view.layoutIfNeeded()起始行,在结束前再次添加。
    猜你喜欢
    • 1970-01-01
    • 2016-09-11
    • 2020-09-10
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多