gpt4 book ai didi

ios - 在 CALayers 上屏蔽 CAGradientLayer

转载 作者:行者123 更新时间:2023-11-28 09:42:52 26 4
gpt4 key购买 nike

在我的场景中,我有 2 个 View :第一个包含 CALayer 实例(条),另一个包含 CAGradientLayer 并放置在第一个上。下图描述了当前状态。

Image

但我需要将此渐变仅应用于第一个 View 的条形 (CALayer)。

enter image description here

我没有找到与我的问题相关的任何信息。任何帮助表示赞赏。

最佳答案

您必须对渐变应用蒙版。有多种方法可以解决这个问题。

您可以创建一个 CAShapeLayer,将形状层的 path 设置为条形,并将渐变层的 mask 设置为该形状形状层。

或者您可以去掉条形层,而是使用两个渐变层,一个用于橙色条,另一个用于灰色条。将两个渐变图层并排放置在 subview 中,并将父 View 的图层蒙版设置为形状图层。以下是如何做到这一点。

您需要两个渐变图层和一个形状图层:

@IBDesignable
class BarGraphView : UIView {

private let orangeGradientLayer = CAGradientLayer()
private let grayGradientLayer = CAGradientLayer()
private let maskLayer = CAShapeLayer()

您还需要条形宽度:

    private let barWidth = CGFloat(9)

在初始化时,设置梯度并添加所有子层:

    override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}

private func commonInit() {
backgroundColor = .black

initGradientLayer(orangeGradientLayer, with: .orange)
initGradientLayer(grayGradientLayer, with: .gray)

maskLayer.strokeColor = nil
maskLayer.fillColor = UIColor.white.cgColor
layer.mask = maskLayer
}

private func initGradientLayer(_ gradientLayer: CAGradientLayer, with color: UIColor) {
gradientLayer.colors = [ color, color, color.withAlphaComponent(0.6), color ].map({ $0.cgColor })
gradientLayer.locations = [ 0.0, 0.5, 0.5, 1.0 ]
layer.addSublayer(gradientLayer)
}

在布局时,设置渐变层的框架并设置 mask 层的路径。这需要一些工作,因为您不希望条形图是一半橙色和一半灰色。

    override func layoutSubviews() {
super.layoutSubviews()

let barCount = ceil(bounds.size.width / barWidth)
let orangeBarCount = floor(barCount / 2)
let grayBarCount = barCount - orangeBarCount

var grayFrame = bounds
grayFrame.size.width = grayBarCount * barWidth
grayFrame.origin.x = frame.maxX - grayFrame.size.width
grayGradientLayer.frame = grayFrame

var orangeFrame = bounds
orangeFrame.size.width -= grayFrame.size.width
orangeGradientLayer.frame = orangeFrame

maskLayer.frame = bounds
maskLayer.path = barPath()
}

private func barPath() -> CGPath {
var columnBounds = self.bounds
columnBounds.origin.x = columnBounds.maxX
columnBounds.size.width = barWidth
let path = CGMutablePath()
for datum in barData.reversed() {
columnBounds.origin.x -= barWidth
let barHeight = CGFloat(datum) * columnBounds.size.height
let barRect = columnBounds.insetBy(dx: 1, dy: (columnBounds.size.height - barHeight) / 2)
path.addRoundedRect(in: barRect, cornerWidth: 2, cornerHeight: 2)
}
return path
}

let barData: [Double] = {
let count = 100
return (0 ..< count).map({ 0.5 + (1 + sin(8.0 * .pi * Double($0) / Double(count))) / 4 })
}()

}

结果:

gradient bars

BarGraphView 在没有条形图的地方是透明的。如果你想让它在深色背景上,在它后面放一个深色 View ,或者让它成为一个深色 View 的 subview :

gradient bars on dark blue

关于ios - 在 CALayers 上屏蔽 CAGradientLayer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43003983/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com