ios - 在 subview 中添加相同的图层会改变其视觉位置

标签 ios swift core-animation calayer swift-playground

我在 View 中添加了一个 subview (带有黑色边框)并将其居中。

然后我用 CAShapeLayer 生成 2 个相同的三角形,并将一个添加到 subview ,另一个添加到主视图。

这是 Playground 中的视觉结果,我们可以看到绿色三角形完全偏离,应该居中。

Playground result

代码如下:

let view = UIView()
let borderedView = UIView()
var containedFrame = CGRect(x: 0, y: 0, width: 100, height: 100)

func setupUI() {
    view.frame = CGRect(x: 0, y: 0, width: 300, height: 600)
    view.backgroundColor = .white
    borderedView.frame = containedFrame
    borderedView.center = view.center
    borderedView.backgroundColor = .clear
    borderedView.layer.borderColor = UIColor.black.cgColor
    borderedView.layer.borderWidth = 1
    view.addSubview(borderedView)
    setupTriangles()
}

private func setupTriangles() {
    view.layer.addSublayer(createTriangle(color: .red)) // RED triangle
    borderedView.layer.addSublayer(createTriangle(color: .green)) // GREEN triangle
}

private func createTriangle(color: UIColor) -> CAShapeLayer {
    let layer = CAShapeLayer()
    let bezierPath = UIBezierPath()
    bezierPath.move(to: CGPoint(x: 0, y: 0))
    bezierPath.addLine(to: CGPoint(x: -containedFrame.width, y: 0))
    bezierPath.addLine(to: CGPoint(x: 0, y: -containedFrame.height))
    bezierPath.close()
    layer.position = borderedView.center
    layer.path = bezierPath.cgPath
    layer.fillColor = color.cgColor
    return layer
}

注意:所有position( View 、borderedView 和两个三角形)都相同(150.0, 300.0)

问题:为什么绿色图层位置不对?

最佳答案

@DuncanC 是正确的,每个 View 都有自己的坐标系。你的问题是这一行:

layer.position = borderedView.center

这将层的位置设置为位于 view 坐标系中的 borderedView 框架的中心。创建绿色三角形时,需要使用borderedView坐标系。

您可以通过将 View 传递给您的 createTriangle 函数来解决此问题,然后使用该 View 的 bounds 的中心作为图层位置:

private func setupTriangles() {
    view.layer.addSublayer(createTriangle(color: .red, for: view)) // RED triangle
    borderedView.layer.addSublayer(createTriangle(color: .green, for: borderedView)) // GREEN triangle
}

private func createTriangle(color: UIColor, for view: UIView) -> CAShapeLayer {
    let layer = CAShapeLayer()
    let bezierPath = UIBezierPath()
    bezierPath.move(to: CGPoint(x: 0, y: 0))
    bezierPath.addLine(to: CGPoint(x: -containedFrame.width, y: 0))
    bezierPath.addLine(to: CGPoint(x: 0, y: -containedFrame.height))
    bezierPath.close()
    layer.position = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
    layer.path = bezierPath.cgPath
    layer.fillColor = color.cgColor
    return layer
}

注意:执行此操作时,绿色三角形直接出现在红色三角形下方,因此不可见。

关于ios - 在 subview 中添加相同的图层会改变其视觉位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49717077/

相关文章:

iphone - 在 iPhone 上传到服务器之前压缩图像大小而不损失质量

ios - iOS 6 上每个组件的 UIPickerView 固定标签问题

swift - 在基于 NSTableView 的 View 中删除和添加行

iphone - 视网膜显示核心图形字体质量

iphone - CALayer 不渲染或绘图

ios - 后台运行 iOS App 超过 10 分钟

ios - 如何使用指向MTLBuffer Swift的指针进行reinterpret_cast

ios - 不同的图像取决于用户屏幕尺寸

ios - RX 按钮点击处理实际上是如何实现的?

objective-c - 如何调试由 UIKit 的 CoreAnimation 调用触发的崩溃?