在uitableViewCell中的UIView内放置渐变颜色
Posted
技术标签:
【中文标题】在uitableViewCell中的UIView内放置渐变颜色【英文标题】:Place gradient color inside UIView in tableViewCell 【发布时间】:2020-10-29 07:10:41 【问题描述】:我在堆栈视图中添加了两个视图。我的 tableViewCell 中有那个堆栈视图。现在我的 stackView 被放置在内容视图的中心,具有宽度和高度。我想在我的 stackView 内的视图内应用渐变颜色。
看看下面的视图 在这种情况下,我给视图设置了我不想要的红色和绿色的背景颜色。我想将四种颜色的渐变应用于此视图。 enter image description here
【问题讨论】:
【参考方案1】:这是我用 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( $0.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)
此进度条支持多种颜色。 只需将您的进度条逻辑替换为我在上面发布的逻辑(或添加进度条下方显示的三角形的逻辑)。
预览:
【讨论】:
【参考方案2】:在 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 $0.cgColor
let layerLocations = locations.map $0 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
【讨论】:
以上是关于在uitableViewCell中的UIView内放置渐变颜色的主要内容,如果未能解决你的问题,请参考以下文章
在 UIScrollView/UIView 内设置 UITableViewCell 样式
UITableViewCell 位置问题内的 UIView - 已更新
更改 UITableViewCell 内 UIView 的高度(故事板)
UItableviewcell中的pangesture,表格滚动无法快速工作