在 tableViewCell 中的 UIView 中放置渐变色
Place gradient color inside UIView in tableViewCell
我在堆栈视图中添加了两个视图。我的 tableViewCell 中有那个堆栈视图。现在我的 stackView 被放置在具有宽度和高度的内容视图的中心。我想在我的 stackView 内的视图中应用渐变颜色。
请看下面的视图 在本例中,我为视图提供了我不想要的红色和绿色背景色。我想将四种颜色的渐变应用于此视图。
enter image description here
下面是我在Swift写的一个简单的进度条代码:
import Foundation
import Cocoa
public class GradientProgressView : NSView
{
// MARK: - Fields
private let bgLayer = CAShapeLayer()
private var progressLayer = CAShapeLayer()
private var gradientLayer = CAGradientLayer()
private var blockLayer = CAShapeLayer()
private var mValue: CGFloat = 0.0
// MARK: - Properties
public var colors: [NSColor] = [NSColor.systemGreen, NSColor.systemYellow, NSColor.sytemRed]
public var value: CGFloat
{
set
{
self.mValue = newValue
if self.mValue > 1.0
{
self.mValue = 1.0
}
if self.mValue < 0.0 || self.mValue.isNaN || self.mValue.isInfinite
{
self.mValue = 0.0
}
self.progressLayer.strokeEnd = self.mValue
}
get
{
return self.mValue
}
}
// MARK: - Overrides
public override func layout()
{
super.layout()
self.initialize()
}
// MARK: - Helper
fileprivate func initialize()
{
self.wantsLayer = true
self.layer?.masksToBounds = true // Optional
self.layer?.cornerRadius = self.bounds.height / 2.0 // Optional
self.bgLayer.removeFromSuperlayer()
self.bgLayer.contentsScale = NSScreen.scale
self.bgLayer.fillColor = NSColor.separatorColor.cgColor
self.bgLayer.path = NSBezierPath(rect: self.bounds).cgPath
self.layer?.addSublayer(self.bgLayer)
self.blockLayer.removeAllAnimations()
self.blockLayer.removeFromSuperlayer()
let path = NSBezierPath()
path.move(to: CGPoint(x: self.bounds.height / 2.0, y: self.bounds.height / 2.0))
path.line(to: CGPoint(x: self.bounds.width - self.bounds.height / 2.0, y: self.bounds.height / 2.0))
self.progressLayer.path = path.cgPath
self.progressLayer.strokeColor = NSColor.black.cgColor
self.progressLayer.fillColor = nil
self.progressLayer.lineWidth = self.bounds.height
self.progressLayer.lineCap = .round
self.progressLayer.strokeStart = 0.0
self.progressLayer.strokeEnd = 0.0
self.progressLayer.contentsScale = NSScreen.scale
self.gradientLayer.removeAllAnimations()
self.gradientLayer.removeFromSuperlayer()
self.gradientLayer.contentsScale = NSScreen.scale
self.gradientLayer.colors = self.colors.map({ [=10=].cgColor })
self.gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
self.gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
self.gradientLayer.mask = self.progressLayer
self.gradientLayer.frame = self.bounds
self.gradientLayer.contentsScale = NSScreen.scale
self.layer?.addSublayer(self.gradientLayer)
}
}
这个进度条支持多种颜色。
只需将您的进度条逻辑替换为我在上面发布的逻辑(或添加进度条下方显示的三角形的逻辑)。
预览:
在 tableViewCell(collectionViewCell) 上创建 GradientLayer
1。在您的 tableViewCell
上创建 CAGradientLayer
实例
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
}
2。将图层框架设置为 layoutSublayers(of:)
的视图边界
如果将图层的框架设置在其他地方,框架会变得很奇怪。
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
// Setting it from layoutSubViews also fine.
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
}
}
3。在视图上添加 GradientLayer。
这是我添加渐变层的 UIView 扩展。
extension UIView {
func addGradient(with layer: CAGradientLayer, gradientFrame: CGRect? = nil, colorSet: [UIColor],
locations: [Double], startEndPoints: (CGPoint, CGPoint)? = nil) {
layer.frame = gradientFrame ?? self.bounds
layer.frame.origin = .zero
let layerColorSet = colorSet.map { [=12=].cgColor }
let layerLocations = locations.map { [=12=] as NSNumber }
layer.colors = layerColorSet
layer.locations = layerLocations
if let startEndPoints = startEndPoints {
layer.startPoint = startEndPoints.0
layer.endPoint = startEndPoints.1
}
self.layer.insertSublayer(layer, above: self.layer)
}
}
* 选项 1 - 从 layoutSublayers(of:)
添加
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
let colorSet = [UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0),
UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)]
let location = [0.2, 1.0]
yourView.addGradient(with: gradientLayer, colorSet: colorSet, locations: location)
}
}
* 选项 2 - 从 cellForRowAt
添加
例如,如果我们有 cellForRowAt
并且像这样,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellId", for: indexPath) as? MyCell {
cell.configureCell(content: someItems[indexPath.row])
}
return UITableViewCell()
}
现在,我们可以处理来自 configureCell(content:)
的 gradientLayer。
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
func configureCell(content: YourType) {
let colorSet = [UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0),
UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)]
let location = [0.2, 1.0]
yourView.addGradient(with: gradientLayer, colorSet: colorSet, locations: location)
}
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
}
}
我在堆栈视图中添加了两个视图。我的 tableViewCell 中有那个堆栈视图。现在我的 stackView 被放置在具有宽度和高度的内容视图的中心。我想在我的 stackView 内的视图中应用渐变颜色。
请看下面的视图 在本例中,我为视图提供了我不想要的红色和绿色背景色。我想将四种颜色的渐变应用于此视图。 enter image description here
下面是我在Swift写的一个简单的进度条代码:
import Foundation
import Cocoa
public class GradientProgressView : NSView
{
// MARK: - Fields
private let bgLayer = CAShapeLayer()
private var progressLayer = CAShapeLayer()
private var gradientLayer = CAGradientLayer()
private var blockLayer = CAShapeLayer()
private var mValue: CGFloat = 0.0
// MARK: - Properties
public var colors: [NSColor] = [NSColor.systemGreen, NSColor.systemYellow, NSColor.sytemRed]
public var value: CGFloat
{
set
{
self.mValue = newValue
if self.mValue > 1.0
{
self.mValue = 1.0
}
if self.mValue < 0.0 || self.mValue.isNaN || self.mValue.isInfinite
{
self.mValue = 0.0
}
self.progressLayer.strokeEnd = self.mValue
}
get
{
return self.mValue
}
}
// MARK: - Overrides
public override func layout()
{
super.layout()
self.initialize()
}
// MARK: - Helper
fileprivate func initialize()
{
self.wantsLayer = true
self.layer?.masksToBounds = true // Optional
self.layer?.cornerRadius = self.bounds.height / 2.0 // Optional
self.bgLayer.removeFromSuperlayer()
self.bgLayer.contentsScale = NSScreen.scale
self.bgLayer.fillColor = NSColor.separatorColor.cgColor
self.bgLayer.path = NSBezierPath(rect: self.bounds).cgPath
self.layer?.addSublayer(self.bgLayer)
self.blockLayer.removeAllAnimations()
self.blockLayer.removeFromSuperlayer()
let path = NSBezierPath()
path.move(to: CGPoint(x: self.bounds.height / 2.0, y: self.bounds.height / 2.0))
path.line(to: CGPoint(x: self.bounds.width - self.bounds.height / 2.0, y: self.bounds.height / 2.0))
self.progressLayer.path = path.cgPath
self.progressLayer.strokeColor = NSColor.black.cgColor
self.progressLayer.fillColor = nil
self.progressLayer.lineWidth = self.bounds.height
self.progressLayer.lineCap = .round
self.progressLayer.strokeStart = 0.0
self.progressLayer.strokeEnd = 0.0
self.progressLayer.contentsScale = NSScreen.scale
self.gradientLayer.removeAllAnimations()
self.gradientLayer.removeFromSuperlayer()
self.gradientLayer.contentsScale = NSScreen.scale
self.gradientLayer.colors = self.colors.map({ [=10=].cgColor })
self.gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
self.gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
self.gradientLayer.mask = self.progressLayer
self.gradientLayer.frame = self.bounds
self.gradientLayer.contentsScale = NSScreen.scale
self.layer?.addSublayer(self.gradientLayer)
}
}
这个进度条支持多种颜色。 只需将您的进度条逻辑替换为我在上面发布的逻辑(或添加进度条下方显示的三角形的逻辑)。
预览:
在 tableViewCell(collectionViewCell) 上创建 GradientLayer
1。在您的 tableViewCell
上创建 CAGradientLayer
实例
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
}
2。将图层框架设置为 layoutSublayers(of:)
的视图边界
如果将图层的框架设置在其他地方,框架会变得很奇怪。
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
// Setting it from layoutSubViews also fine.
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
}
}
3。在视图上添加 GradientLayer。
这是我添加渐变层的 UIView 扩展。
extension UIView {
func addGradient(with layer: CAGradientLayer, gradientFrame: CGRect? = nil, colorSet: [UIColor],
locations: [Double], startEndPoints: (CGPoint, CGPoint)? = nil) {
layer.frame = gradientFrame ?? self.bounds
layer.frame.origin = .zero
let layerColorSet = colorSet.map { [=12=].cgColor }
let layerLocations = locations.map { [=12=] as NSNumber }
layer.colors = layerColorSet
layer.locations = layerLocations
if let startEndPoints = startEndPoints {
layer.startPoint = startEndPoints.0
layer.endPoint = startEndPoints.1
}
self.layer.insertSublayer(layer, above: self.layer)
}
}
* 选项 1 - 从 layoutSublayers(of:)
添加
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
let colorSet = [UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0),
UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)]
let location = [0.2, 1.0]
yourView.addGradient(with: gradientLayer, colorSet: colorSet, locations: location)
}
}
* 选项 2 - 从 cellForRowAt
添加
例如,如果我们有 cellForRowAt
并且像这样,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellId", for: indexPath) as? MyCell {
cell.configureCell(content: someItems[indexPath.row])
}
return UITableViewCell()
}
现在,我们可以处理来自 configureCell(content:)
的 gradientLayer。
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
func configureCell(content: YourType) {
let colorSet = [UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0),
UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)]
let location = [0.2, 1.0]
yourView.addGradient(with: gradientLayer, colorSet: colorSet, locations: location)
}
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
}
}