gpt4 book ai didi

ios - 为 CAGradientLayer 添加 mask 使 UIBezierPath 消失

转载 作者:搜寻专家 更新时间:2023-10-31 19:32:29 24 4
gpt4 key购买 nike

我想为带有渐变的 View 添加内边框。下面的代码有效并给了我这个结果

enter image description here

import UIKit

class InnerGradientBorderView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = UIColor.clear
}

override func draw(_ rect: CGRect) {
super.draw(rect)

addGradientInnerBorder(width: 8, color: FlatWhite())
}

func addGradientInnerBorder(width: CGFloat, color: UIColor) {

// Setup
let topLeftO = CGPoint(x: 0, y: 0)
let topLeftI = CGPoint(x: width, y: width)

let topRightO = CGPoint(x: frame.width, y: 0)
let topRightI = CGPoint(x: frame.width - width, y: width)

let bottomLeftO = CGPoint(x: 0, y: frame.height)
let bottomLeftI = CGPoint(x: width, y: frame.height - width)

let bottomRightO = CGPoint(x: frame.width, y: frame.height)
let bottomRightI = CGPoint(x: frame.width - width, y: frame.height - width)

// Top
let topPoints = [topLeftO, topLeftI, topRightI, topRightO, topLeftO]
let topGradientPoints = [CGPoint(x: 0, y: 0), CGPoint(x: 0, y: 1)]
addGradientToBeizerPath(path: addClosedPathForPoints(points: topPoints), color: color, gradientPoints: topGradientPoints)

// Left
let leftPoints = [topLeftO, topLeftI, bottomLeftI, bottomLeftO, topLeftO]
let leftGradientPoints = [CGPoint(x: 0, y: 0), CGPoint(x: 1, y: 0)]
addGradientToBeizerPath(path: addClosedPathForPoints(points: leftPoints), color: color, gradientPoints: leftGradientPoints)

// Right
let rightPoints = [topRightO, topRightI, bottomRightI, bottomRightO, topRightO]
let rightGradientPoints = [CGPoint(x: 1, y: 0), CGPoint(x: 0, y: 0)]
addGradientToBeizerPath(path: addClosedPathForPoints(points: rightPoints), color: color, gradientPoints: rightGradientPoints)

// Bottom
let bottomPoints = [bottomLeftO, bottomLeftI, bottomRightI, bottomRightO, bottomLeftO]
let bottomGradientPoints = [CGPoint(x: 0, y: 1), CGPoint(x: 0, y: 0)]
addGradientToBeizerPath(path: addClosedPathForPoints(points: bottomPoints), color: color, gradientPoints: bottomGradientPoints)
}

func addClosedPathForPoints(points: [CGPoint]) -> UIBezierPath? {
guard points.count == 5 else { return nil }

let path = UIBezierPath()
path.move(to: points[0])
path.addLine(to: points[1])
path.addLine(to: points[2])
path.addLine(to: points[3])
path.addLine(to: points[4])

path.close()

return path
}

func addGradientToBeizerPath(path: UIBezierPath?, color: UIColor, gradientPoints: [CGPoint]) {
guard let path = path, gradientPoints.count == 2 else { return }

let gradient = CAGradientLayer()
gradient.frame = path.bounds
gradient.colors = [color.cgColor, UIColor.clear.cgColor]
gradient.startPoint = gradientPoints[0]
gradient.endPoint = gradientPoints[1]

// let shapeMask = CAShapeLayer()
// shapeMask.path = path.cgPath
// gradient.mask = shapeMask

self.layer.insertSublayer(gradient, at: 0)
}
}

你会注意到边缘看起来不太好。为了解决这个问题,我给边缘一个角度。当我用这个角度对这个渐变应用蒙版时,右边和底部的路径会像这样消失:

enter image description here

我在这里所做的就是使用一些封闭的 bezierPaths 并对其应用渐变。如果渐变有掩码(注释代码未注释),则其中两条路径消失。我觉得我不理解某些东西,所以希望这里有人能告诉我如何正确使用 CAShapeLayer。

最佳答案

This commentCALayer mask property完美解释:

The mask layer lives in the masked layer's coordinate system just as if it were a sublayer.

在你的情况下,右侧和底部渐变层的原点不是在封闭 View 的 (0, 0),但在 (frame.width - width, 0)(frame.height - width, 0) 分别。另一方面,点的坐标oshapeMask.path 相对于封闭 View 的 (0, 0)

一个可能的简单解决方法是转换坐标系形状层,以便它使用与点相同的坐标给定路径的:

    let gradient = CAGradientLayer()
gradient.frame = path.bounds
gradient.bounds = path.bounds // <<--- ADDED HERE!
gradient.colors = [color.cgColor, UIColor.clear.cgColor]
gradient.startPoint = gradientPoints[0]
gradient.endPoint = gradientPoints[1]

let shapeMask = CAShapeLayer()
shapeMask.path = path.cgPath
gradient.mask = shapeMask

self.layer.addSublayer(gradient)

关于ios - 为 CAGradientLayer 添加 mask 使 UIBezierPath 消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47897825/

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