CAShapelayer 在 UIView 的子层中的错误位置
Wrong position of CAShapelayer in sublayers of UIView
我正在尝试绘制:O-O-O 在 UIView 的中间但得到:
这是计算 CAShapeLayer.frame 位置的函数。偶数索引是点,奇数索引是线。行数总是减去一个点数。
func frameForShape(at index: Int) -> CGRect {
let dotWidth = dotRadius * 2
let lineWidth = (view.bounds.width - (CGFloat(numberOfDots) * dotWidth)) / CGFloat(numberOfLines)
if index % 2 == 0 {
let count = CGFloat(index) / 2
let x = (lineWidth * count) + (dotWidth * count)
return CGRect(x: x, y: 0, width: dotWidth, height: view.bounds.height)
} else {
let count = Double(index) / 2
let x = (lineWidth * CGFloat(floor(count))) + (dotWidth * CGFloat(ceil(count)))
return CGRect(x: x, y: 0, width: lineWidth, height: view.bounds.height)
}
}
func setFrame() {
for (index, shape) in shapes.enumerated() {
shape.frame = frameForShape(at: index)
}
}
frameForShape(at:) 正确 return 框架位置和大小
此函数在给定帧的中心绘制一条路径
func linePath(rect: CGRect) -> UIBezierPath {
let newRect = CGRect(x: rect.minX, y: rect.midY - (lineHeight / 2), width: rect.width, height: lineHeight)
let path = UIBezierPath(rect: newRect)
return path
}
func dotPath(rect: CGRect) -> UIBezierPath {
let newRect = CGRect(x: rect.midX - dotRadius, y: rect.midY - dotRadius, width: dotRadius * 2, height: dotRadius * 2)
let path = UIBezierPath(ovalIn: newRect)
return path
}
在这里,我将 CAShapeLayers 添加到黄色 UIView
override func awakeFromNib() {
super.awakeFromNib()
for shape in shapes {
view.layer.addSublayer(shape)
}
}
override func layoutSubviews() {
super.layoutSubviews()
layoutIfNeeded()
setFrame()
build()
}
func build() {
for (index, shape) in shapes.enumerated() {
if index % 2 == 0 {
shape.path = dotPath(rect: shape.frame).cgPath
} else {
shape.path = linePath(rect: shape.frame).cgPath
}
}
}
框架是正确的,为什么点和线放错了?
我找到了这个答案:
incorrect position of your layer - frame should be equal to bounds of parent layer in parentView
但是如果 UIBezierPath(ovalIn:) 和 UIBezierPath(rect:) 都绘制在框架内,如何在特定位置绘制路径?
正如答案所说,只需在调用 build() 时将 shape.frame 更改为 shape.bounds。
请记住,形状图层的坐标是相对于包含视图的坐标,因此需要使用边界。
我正在尝试绘制:O-O-O 在 UIView 的中间但得到:
这是计算 CAShapeLayer.frame 位置的函数。偶数索引是点,奇数索引是线。行数总是减去一个点数。
func frameForShape(at index: Int) -> CGRect {
let dotWidth = dotRadius * 2
let lineWidth = (view.bounds.width - (CGFloat(numberOfDots) * dotWidth)) / CGFloat(numberOfLines)
if index % 2 == 0 {
let count = CGFloat(index) / 2
let x = (lineWidth * count) + (dotWidth * count)
return CGRect(x: x, y: 0, width: dotWidth, height: view.bounds.height)
} else {
let count = Double(index) / 2
let x = (lineWidth * CGFloat(floor(count))) + (dotWidth * CGFloat(ceil(count)))
return CGRect(x: x, y: 0, width: lineWidth, height: view.bounds.height)
}
}
func setFrame() {
for (index, shape) in shapes.enumerated() {
shape.frame = frameForShape(at: index)
}
}
frameForShape(at:) 正确 return 框架位置和大小
此函数在给定帧的中心绘制一条路径
func linePath(rect: CGRect) -> UIBezierPath {
let newRect = CGRect(x: rect.minX, y: rect.midY - (lineHeight / 2), width: rect.width, height: lineHeight)
let path = UIBezierPath(rect: newRect)
return path
}
func dotPath(rect: CGRect) -> UIBezierPath {
let newRect = CGRect(x: rect.midX - dotRadius, y: rect.midY - dotRadius, width: dotRadius * 2, height: dotRadius * 2)
let path = UIBezierPath(ovalIn: newRect)
return path
}
在这里,我将 CAShapeLayers 添加到黄色 UIView
override func awakeFromNib() {
super.awakeFromNib()
for shape in shapes {
view.layer.addSublayer(shape)
}
}
override func layoutSubviews() {
super.layoutSubviews()
layoutIfNeeded()
setFrame()
build()
}
func build() {
for (index, shape) in shapes.enumerated() {
if index % 2 == 0 {
shape.path = dotPath(rect: shape.frame).cgPath
} else {
shape.path = linePath(rect: shape.frame).cgPath
}
}
}
框架是正确的,为什么点和线放错了?
我找到了这个答案:
incorrect position of your layer - frame should be equal to bounds of parent layer in parentView
但是如果 UIBezierPath(ovalIn:) 和 UIBezierPath(rect:) 都绘制在框架内,如何在特定位置绘制路径?
正如答案所说,只需在调用 build() 时将 shape.frame 更改为 shape.bounds。
请记住,形状图层的坐标是相对于包含视图的坐标,因此需要使用边界。