简体   繁体   English

CAShapelayer在UIView子层中的位置错误

[英]Wrong position of CAShapelayer in sublayers of UIView

I'm trying to draw: OOO in the midY of UIView but get: 我试图在UIView的中部绘制:OOO,但得到:

图层位置错误

Here is a func for calculating position for CAShapeLayer.frame. 这是一个用于计算CAShapeLayer.frame位置的函数。 Even indices are dots and odd indices are lines. 偶数索引是点,奇数索引是线。 Number of lines is always minus one number of dots. 行数总是减去一个点数。

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:) correctly return frame position and size frameForShape(at :)正确返回框架位置和大小

frameForShape的结果(在:)

This funcs draw a path in the center of given frame 该功能在给定框架的中心绘制路径

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
}

Here, I'm adding CAShapeLayers to yellow UIView 在这里,我将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
        }
    }
}

Frames are correct so why dots and lines are misplaced? 框架是正确的,那么为什么点和线放错了位置?

I found this answer: https://stackoverflow.com/a/40194019/ 我找到了这个答案: https : //stackoverflow.com/a/40194019/

incorrect position of your layer - frame should be equal to bounds of parent layer in parentView 图层的位置不正确-框架应等于parentView中父图层的边界

But how draw path at specific position if UIBezierPath(ovalIn:) and UIBezierPath(rect:) draw all inside frame? 但是,如果UIBezierPath(ovalIn :)和UIBezierPath(rect :)绘制所有内部框架,如何在特定位置绘制路径?

As the answer says, simply change shape.frame to shape.bounds in your call to build(). 正如答案所说,只需在对build()的调用中将shape.frame更改为shape.bounds即可。

Remember that the coordinates of your shape layer are relative to the containing view, so bounds needs to be used. 请记住,形状图层的坐标是相对于包含视图的,因此需要使用边界。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM