CAShaperLayer 作为蒙版仅显示 UIView 的 1/4
CAShaperLayer as mask show only 1/4 of UIView
我有创建路径并设置为遮罩的方法,但它显示为视图的 1/4。我需要设置其他东西吗?看起来像视网膜问题或坐标问题,但不确定是哪个。
func layoutZigZag(bounds: CGRect) -> CALayer {
let maskLayer = CAShapeLayer()
maskLayer.bounds = bounds
let path = UIBezierPath()
let width = bounds.size.width
let height = bounds.size.height
let topRight = CGPoint(x: width , y: height)
let topLeft = CGPoint(x: 0 , y: height)
let bottomRight = CGPoint(x: width , y: 0)
let bottomLeft = CGPoint(x: 0 , y: 0)
let zigzagHeight: CGFloat = 10
let numberOfZigZag = Int(floor(width / 23.0))
let zigzagWidth = width / CGFloat(numberOfZigZag)
path.move(to: topLeft)
path.addLine(to: bottomLeft)
// zigzag
var currentX = bottomLeft.x
var currentY = bottomLeft.y
for i in 0..<numberOfZigZag {
let upper = CGPoint(x: currentX + zigzagWidth / 2, y: currentY + zigzagHeight)
let lower = CGPoint(x: currentX + zigzagWidth, y: currentY)
path.addLine(to: upper)
path.addLine(to: lower)
currentX += zigzagWidth
}
path.addLine(to: topRight)
path.close()
maskLayer.path = path.cgPath
return maskLayer
}
and
let rect = CGRect(x: 0, y: 0, width: 320, height: 400)
let view = UIView(frame: rect)
view.backgroundColor = UIColor.red
let zigzag = layoutZigZag(bounds: rect)
view.layer.mask = zigzag
路径正确
结果是视图的 1/4
将maskLayer.bounds = bounds
更改为maskLayer.frame = bounds
更新:
颠倒是因为 UI 和 CG 之间的差异,我们在 UIBezierPath 中创建路径并将该路径转换为 CGPath (maskLayer.path = path.cgPath
)。首先我们要知道区别,CGPath is Quartz 2D and origin is at the bottom left while in UIBezierPath is UIKit 原点在左上角。根据您的代码,应用的坐标是按照左上角的,即 UIBezierPath 当我们转换为 CGPath(原点在左下角)时,它会颠倒过来。所以更改代码如下以获得所需的效果。
let topRight = CGPoint(x: width , y: 0)
let topLeft = CGPoint(x: 0 , y: 0)
let bottomLeft = CGPoint(x: 0 , y: (height - zigzagHeight))
石英二维坐标系
UIBezierPath 坐标系
我有创建路径并设置为遮罩的方法,但它显示为视图的 1/4。我需要设置其他东西吗?看起来像视网膜问题或坐标问题,但不确定是哪个。
func layoutZigZag(bounds: CGRect) -> CALayer {
let maskLayer = CAShapeLayer()
maskLayer.bounds = bounds
let path = UIBezierPath()
let width = bounds.size.width
let height = bounds.size.height
let topRight = CGPoint(x: width , y: height)
let topLeft = CGPoint(x: 0 , y: height)
let bottomRight = CGPoint(x: width , y: 0)
let bottomLeft = CGPoint(x: 0 , y: 0)
let zigzagHeight: CGFloat = 10
let numberOfZigZag = Int(floor(width / 23.0))
let zigzagWidth = width / CGFloat(numberOfZigZag)
path.move(to: topLeft)
path.addLine(to: bottomLeft)
// zigzag
var currentX = bottomLeft.x
var currentY = bottomLeft.y
for i in 0..<numberOfZigZag {
let upper = CGPoint(x: currentX + zigzagWidth / 2, y: currentY + zigzagHeight)
let lower = CGPoint(x: currentX + zigzagWidth, y: currentY)
path.addLine(to: upper)
path.addLine(to: lower)
currentX += zigzagWidth
}
path.addLine(to: topRight)
path.close()
maskLayer.path = path.cgPath
return maskLayer
}
and
let rect = CGRect(x: 0, y: 0, width: 320, height: 400)
let view = UIView(frame: rect)
view.backgroundColor = UIColor.red
let zigzag = layoutZigZag(bounds: rect)
view.layer.mask = zigzag
路径正确
结果是视图的 1/4
将maskLayer.bounds = bounds
更改为maskLayer.frame = bounds
更新:
颠倒是因为 UI 和 CG 之间的差异,我们在 UIBezierPath 中创建路径并将该路径转换为 CGPath (maskLayer.path = path.cgPath
)。首先我们要知道区别,CGPath is Quartz 2D and origin is at the bottom left while in UIBezierPath is UIKit 原点在左上角。根据您的代码,应用的坐标是按照左上角的,即 UIBezierPath 当我们转换为 CGPath(原点在左下角)时,它会颠倒过来。所以更改代码如下以获得所需的效果。
let topRight = CGPoint(x: width , y: 0)
let topLeft = CGPoint(x: 0 , y: 0)
let bottomLeft = CGPoint(x: 0 , y: (height - zigzagHeight))
石英二维坐标系
UIBezierPath 坐标系