【问题标题】:Swift 3 put 2 colors in the same UIViewSwift 3 将 2 种颜色放在同一个 UIView 中
【发布时间】:2017-10-06 06:46:09
【问题描述】:

我想在 UIViews 和 UIImageViews 上实现这个效果:

在 UIView 上,我知道我可以在其中放入 2 个不同颜色的,但我认为一定有更好的方法,但我不知道如何在 UIImageVIew 中做到这一点。某种 pod 会非常有用,因为我找不到。

【问题讨论】:

  • 你应该使用两种颜色的图像。它比尝试在图像视图中放置两种颜色更相关。为什么要放两种颜色?改用图片!
  • 在这里请求教程或库不是一个有效的话题。
  • 问题是当它“未激活”时我需要将其设为灰色,并且我无法在其上应用正常色调,因为灰色将有 2 种颜色
  • @ElTomato 代码在这里完全可以,我只是说我更喜欢 pod,因为它使事情变得更容易。如果您有有效的方法,我将不胜感激。

标签: ios swift uiview uiimageview


【解决方案1】:

您可以添加一个渐变层,而不是从一种颜色过渡到另一种颜色,而是从一种颜色变为相同颜色直到中间点,下半部分也是如此。检查示例:

let twoColorView = UIView(frame: CGRect(x: 40, y: 100, width: 200, height: 100))
let gradientLayer = CAGradientLayer()
gradientLayer.frame = twoColorView.bounds
gradientLayer.colors = [UIColor.red.cgColor, UIColor.red.cgColor, UIColor.blue.cgColor, UIColor.blue.cgColor]
gradientLayer.locations = [NSNumber(value: 0.0), NSNumber(value: 0.5), NSNumber(value: 0.5), NSNumber(value: 1.0)]
twoColorView.layer.addSublayer(gradientLayer)

当然,您可以进一步设置该视图的样式,例如:

twoColorView.layer.cornerRadius = twoColorView.bounds.height / 2
twoColorView.layer.masksToBounds = true

结果如下:

编辑

它可以泛化为接受任意数量的颜色。创建一个UIView 扩展并在那里添加你的逻辑。这样颜色就可以应用于任何UIView及其子类,如UILabel、UIButton、UIImageView等。

extension UIView {
    func addColors(colors: [UIColor]) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = self.bounds

        var colorsArray: [CGColor] = []
        var locationsArray: [NSNumber] = []
        for (index, color) in colors.enumerated() {
            // append same color twice
            colorsArray.append(color.cgColor)
            colorsArray.append(color.cgColor)
            locationsArray.append(NSNumber(value: (1.0 / Double(colors.count)) * Double(index)))
            locationsArray.append(NSNumber(value: (1.0 / Double(colors.count)) * Double(index + 1)))
        }

        gradientLayer.colors = colorsArray
        gradientLayer.locations = locationsArray

        self.backgroundColor = .clear
        self.layer.addSublayer(gradientLayer)

        // This can be done outside of this funciton
        self.layer.cornerRadius = self.bounds.height / 2
        self.layer.masksToBounds = true
    }
}

并添加颜色:

    let colorView = UIImageView(frame: CGRect(x: 40, y: 100, width: 200, height: 100))
    colorView.addColors(colors: [.red, .green, .blue])
    view.addSubview(colorView)

这是结果:

注意不要在视图的生命周期中多次调用这个函数,因为它会在彼此之上添加子层。因此,要么调用一次,要么在再次调用addColors 之前删除子层。所以当然还有改进的余地。

【讨论】:

  • 如果您指定您的问题,也许有人会帮助您。
  • UITableViewCell 很大程度上取决于UITableView 的显示方式——您需要考虑单元格的重用、时间安排(例如,尝试在willDisplayCell 中设置)和单元格的子视图(contentView)。但如果没有进一步的信息,我无法判断你出了什么问题。
【解决方案2】:

Swift 4 中更加静态和客观的方式,

class ColouredView: UIView {
    override class var layerClass : AnyClass {
        return ColouredLayer.self
    }
}


class ColouredLayer: CAGradientLayer{

    override init() {
        super.init()

        let colors = [UIColor.red, UIColor.blue]
        addColors(colors)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


}


extension CAGradientLayer{

    func addColors(_ colors: [UIColor]){
        var colorsArray: [CGColor] = []
        var locationsArray: [NSNumber] = []
        for (index, color) in colors.enumerated() {
            // append same color twice
            colorsArray.append(color.cgColor)
            colorsArray.append(color.cgColor)
            locationsArray.append(NSNumber(value: (1.0 / Double(colors.count)) * Double(index)))
            locationsArray.append(NSNumber(value: (1.0 / Double(colors.count)) * Double(index + 1)))
        }

        self.colors = colorsArray
        locations = locationsArray
    }
}

只需设置和分配ColouredView

感谢@Au Ris 的回答

【讨论】:

    【解决方案3】:

    通过方向改进上述答案

    extension UIView {
    
    enum GradientDirection {
        case horizontal
        case vertical
    }
    
    func fillColors(_ colors: [UIColor], withPercentage percentages: [Double], direction: GradientDirection = .horizontal) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = bounds
        var colorsArray: [CGColor] = []
        var locationsArray: [NSNumber] = []
        var total = 0.0
        locationsArray.append(0.0)
        for (index, color) in colors.enumerated() {
            // append same color twice
            colorsArray.append(color.cgColor)
            colorsArray.append(color.cgColor)
            // Calculating locations w.r.t Percentage of each
            if index + 1 < percentages.count {
                total += percentages[index]
                let location = NSNumber(value: total / 100)
                locationsArray.append(location)
                locationsArray.append(location)
            }
        }
        locationsArray.append(1.0)
        if direction == .horizontal {
            gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
            gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
        } else {
            gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
            gradientLayer.endPoint = CGPoint(x: 0.0, y: 1.0)
        }
        gradientLayer.colors = colorsArray
        gradientLayer.locations = locationsArray
        backgroundColor = .clear
        layer.addSublayer(gradientLayer)
    }
        }
    

    【讨论】:

      【解决方案4】:

      它可以更概括地接受任意数量的颜色,以及它们各自的百分比

      extension UIView {
          func addColors(colors: [UIColor], withPercentage percentages: [Double]) {
              let gradientLayer = CAGradientLayer()
              gradientLayer.frame = self.bounds
              var colorsArray: [CGColor] = []
              var locationsArray: [NSNumber] = []
              var total = 0.0
              locationsArray.append(0.0)
              for (index, color) in colors.enumerated() {
                  // append same color twice
                  colorsArray.append(color.cgColor)
                  colorsArray.append(color.cgColor)
                  // Calculating locations w.r.t Percentage of each
                  if index+1 < percentages.count{
                      total += percentages[index]
                      let location: NSNumber = NSNumber(value: total/100)
                      locationsArray.append(location)
                      locationsArray.append(location)
                  }
              }
              locationsArray.append(1.0)
              gradientLayer.colors = colorsArray
              gradientLayer.locations = locationsArray
              self.backgroundColor = .clear
              self.layer.addSublayer(gradientLayer)
          }
      }
      

      用法:

      let colors: [UIColor] = [.red, .green, .blue, .yellow, .purple]
      let percentages: [Double] = [10, 30, 20, 5, 35]
      testView.addColors(colors: colors, withPercentage: percentages)
      

      结果:

      感谢@Au Ris 的回答

      【讨论】:

      • 嗨,我有一个简短的问题。我可以在填充颜色时添加动画吗?它为 UIView 设置动画并将颜色填充。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-30
      相关资源
      最近更新 更多