【问题标题】:Adding a CAShapeLayer to a subView将 CAShapeLayer 添加到子视图
【发布时间】:2018-12-27 11:09:20
【问题描述】:

我尝试将 CAShapeLayer 添加到主视图(单视图应用程序)上的较小 UIView。我有形状图层动画并响应触摸手势开始绘制它。但它是从主视图的中心绘制的,我需要能够移动它并限制它以进行布局。我看过另一篇似乎有同样问题的帖子,但我想我让自己更加困惑。我在主 ViewController 的 viewDidLoad 函数中有以下代码。

这是我正在玩的一个测试项目,一旦我的现有应用程序运行,它就会向它添加新功能。

我尝试在项目的 MainStoryBoard 中添加 UIView 并将其添加到 ViewController.swift 文件(控制拖动)以创建插座,然后将 shapeLayer 和 trackLayer 添加到 UIView。

代码如下

@IBOutlet weak var gaugeView: UIView!


override func viewDidLoad() {
    super.viewDidLoad()

    let centre = view.center

    let circularPath = UIBezierPath(arcCenter: centre, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)

    // Track Layer Under Gauge
    trackLayer.path = circularPath.cgPath
    trackLayer.strokeColor = UIColor.lightGray.cgColor
    trackLayer.lineWidth = 10
    trackLayer.fillColor = UIColor.clear.cgColor
    //view.layer.addSublayer(trackLayer)
    gaugeView.layer.addSublayer(trackLayer)

    // Animated Circular Guage
    shapeLayer.path = circularPath.cgPath
    shapeLayer.strokeColor = UIColor.green.cgColor
    shapeLayer.lineWidth = 10
    shapeLayer.lineCap = .round
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeEnd = 0
    //view.layer.addSublayer(shapeLayer)
    gaugeView.layer.addSublayer(shapeLayer)
  }

一旦我在模拟器中拥有应用程序,它会在 view.layer.addSubLayer 未被注释掉但不会将其添加到具有 gaugeView.layer.addSubView 的 UIView 容器中时绘制并动画圆。

【问题讨论】:

  • 你要画一个圆吗?
  • 我已经有一段时间没有使用子图层了,但是添加的子图层是否可能在框架之外并且视图具有clipsToBounds true?
  • 是的,它适用于主视图,但不适用于 uiview 我需要它,我可以在主故事板中包含它。
  • 创建一个 UIView 的自定义类,它是圆形视图,并将其放在 main.storyboard 上,然后将一个自定义类分配给 UIView。 @MikeyC
  • @AbhishekJadhav 好的,这是否也允许我将变量传递给 UIView 以确定正在绘制的圆圈的属性?即颜色和圆圈画多远?它将用作计时器倒计时的进度指示器。

标签: swift uiview subview cashapelayer


【解决方案1】:

您需要在此处将center 设置为gaugeView center 而不是view.center

override func viewDidLoad() {
    super.viewDidLoad()

    let centre = CGPoint(x: gaugeView.frame.width/2, y: gaugeView.frame.height/2)
    ...
}

注意:在使用Autolayout 时,viewDidLoad 绝不是在subView 中使用frame 的正确位置,autolayout 尚未布局。获取和使用frame 的最佳地点是viewDidLayoutSubviews

【讨论】:

  • 刚才试过了,看模拟器的第二个屏幕转储图片。
  • 这只是抛出一个错误,因为 UIBezierPath 想要一个 CGpoint 而 .bounds 是一个 CGRect
  • 是的。这应该修复。 let centre = CGPoint(x: gaugeView.frame.width/2, y: gaugeView.frame.height/2)
  • 天才,解决了它。请注意,我确实在这里的上一个问题中尝试过,但我认为我忘记了末尾的 /2。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多