【问题标题】:Fill color not working using CAShapeLayer in swift在 swift 中使用 CAShapeLayer 填充颜色不起作用
【发布时间】:2020-02-13 10:07:13
【问题描述】:

我正在尝试下面的代码来绘制形状,这没关系,但 UIView 背景颜色 没有显示,因为我已将橙色颜色赋予 View

查看我的代码:

let myView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
myView.backgroundColor = .orange
let circlePath = UIBezierPath(arcCenter: CGPoint(x: myView.bounds.size.width / 2, y: 0), radius: myView.bounds.size.height, startAngle: 0.0, endAngle: .pi, clockwise: false)
let circleShape = CAShapeLayer()
circleShape.masksToBounds = false
circleShape.path = circlePath.cgPath
circleShape.fillColor = UIColor.orange.cgColor
circleShape.strokeColor = UIColor.orange.cgColor
myView.layer.mask = circleShape
print(myView)

在操场上的输出:

【问题讨论】:

    标签: ios swift swift5.2


    【解决方案1】:

    试试这个代码:

        let myView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
        myView.backgroundColor = .orange
        let circlePath = UIBezierPath(arcCenter: myView.center,
                                      radius: myView.bounds.size.width / 2,
                                      startAngle: 0.0,
                                      endAngle: .pi,
                                      clockwise: false)
        let circleShape = CAShapeLayer()
        circleShape.path = circlePath.cgPath
        myView.layer.mask = circleShape
    

    我认为您看不到预期结果是因为 arcCenter 或开始和结束天使错误

    代码结果:

    【讨论】:

      【解决方案2】:

      问题似乎出在您的circlePath 上,有:

      1) arcCenter 错误(CGPoint 的y 未居中)

      2) 半径(它应该是视图高度/宽度的一半,考虑到height = width 并且您需要一个圆)

      3) 角度(应该是360度)

      将其定义替换为:

      let circlePath = UIBezierPath(arcCenter: myView.center, radius: myView.bounds.height/2, startAngle: 0.0, endAngle: .pi * 2, clockwise: false)
      

      它应该按预期工作......

      没关系,但 UIView 背景颜色没有显示,因为我已经给出 橙色查看

      您使用的路径甚至不显示图层,因为您已将其角半径指定为与其高度相同,并且您已将生成的所谓不可见图层应用为视图的蒙版。

      【讨论】:

        【解决方案3】:

        一些观察:

        1. 您只是在查看路径的视觉表示,而不是视图。要查看视图,您应该设置PlaygroundPageliveView

          import PlaygroundSupport
          

          PlaygroundPage.current.liveView = myView
          PlaygroundPage.current.needsIndefiniteExecution = true
          
        2. 顺便说一句,你的圆形视图是从 0 逆时针到 π。 IE。那是一个圆圈的上半部分。因此,如果圆的中心有 y0,这意味着您的路径在视图上方并且不与视图重叠。将其设置为顺时针方向(以获得圆的下半部分)或将y 向下移动(使圆的上半部分与视图重叠)。

        3. 我发现 Playground 会调整其 liveView 的大小(即使我将 wantsFullScreenLiveView 设置为 false),所以如果我想要特定大小的视图,我会使用“容器视图”。即,我将添加myView 作为containerView 的子视图,添加约束以将其放在该容器的中心,然后将containerView 设置为liveView

        4. 仅相切相关,但您将蒙版形状图层的颜色设置为橙色。蒙版只使用它们的 alpha 通道,所以使用橙色是没有意义的。我们通常将遮罩设置为白色,但我只是想确保我们不会将遮罩的颜色与遮罩视图的颜色混为一谈。

        所以,把所有这些放在一起:

        import UIKit
        import PlaygroundSupport
        
        // create container
        let containerView = UIView()
        containerView.translatesAutoresizingMaskIntoConstraints = false
        
        // create view that we'll mask with shape layer
        let rect = CGRect(x: 0, y: 0, width: 200, height: 200)
        let myView = UIView()
        myView.translatesAutoresizingMaskIntoConstraints = false
        myView.backgroundColor = .orange
        myView.clipsToBounds = true
        containerView.addSubview(myView)
        
        // create mask
        let circlePath = UIBezierPath(arcCenter: CGPoint(x: rect.midX, y: rect.minY), radius: rect.height, startAngle: 0, endAngle: .pi, clockwise: true)
        let circleShape = CAShapeLayer()
        circleShape.masksToBounds = false
        circleShape.path = circlePath.cgPath
        circleShape.fillColor = UIColor.white.cgColor
        circleShape.strokeColor = UIColor.white.cgColor
        myView.layer.mask = circleShape
        
        // center masked view in container
        NSLayoutConstraint.activate([
            myView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
            myView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
            myView.widthAnchor.constraint(equalToConstant: 200),
            myView.heightAnchor.constraint(equalToConstant: 200)
        ])
        
        // show it
        PlaygroundPage.current.liveView = containerView
        PlaygroundPage.current.needsIndefiniteExecution = true
        

        产生:

        因此,通过使弧顺时针方向移动并使用liveView,我们现在可以看到它。显然,圆心在midX, minY 且半径为height 的圆弧不能显示完整的半圆。如果您想看到完整的半圆,则必须将半径设置为 width / 2(或增加 widthrect 或其他)。

        【讨论】:

          【解决方案4】:

          只需 在绘图后随处删除 path.move(to:) 调用。这帮助我解决了同样的问题

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-02-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多