Swift 3 将 2 种颜色放在同一个 UIView 中
Posted
技术标签:
【中文标题】Swift 3 将 2 种颜色放在同一个 UIView 中【英文标题】:Swift 3 put 2 colors in the same UIView 【发布时间】:2017-10-06 06:46:09 【问题描述】:我想在 UIViews 和 UIImageViews 上实现这个效果:
在 UIView 上,我知道我可以在其中放入 2 个不同颜色的,但我认为一定有更好的方法,但我不知道如何在 UIImageVIew 中做到这一点。某种 pod 会非常有用,因为我找不到。
【问题讨论】:
你应该使用两种颜色的图像。它比尝试在图像视图中放置两种颜色更相关。为什么要放两种颜色?改用图片! 在这里请求教程或库不是一个有效的话题。 问题是当它“未激活”时我需要将其设为灰色,并且我无法在其上应用正常色调,因为灰色将有 2 种颜色 @ElTomato 代码在这里完全可以,我只是说我更喜欢 pod,因为它使事情变得更容易。如果您有有效的方法,我将不胜感激。 【参考方案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 设置动画并将颜色填充。谢谢!以上是关于Swift 3 将 2 种颜色放在同一个 UIView 中的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 3 中更改 tableView 中的图像颜色
Swift iOS Sprite Kit - 将精灵从一种颜色淡化为另一种颜色[关闭]