【问题标题】:How can I fill the inside of a UIBezierPath with Swift?如何用 Swift 填充 UIBezierPath 的内部?
【发布时间】:2020-05-25 18:50:33
【问题描述】:

我正在尝试使用 Swift 5 填充 UIBezierPath,但是当我尝试运行我的函数来为路径着色时,我遇到了很多错误。它们都不是致命的,因此构建成功,但路径未绘制在屏幕上。我附上了相关代码和两个错误。提前致谢。

func colorPaths() {    
                let path = leftCorner //Where leftCorner isa UIBezierPath

                let fillColor = UIColor.white
                fillColor.setFill()

                path.lineWidth = 1.0
                let strokeColor = UIColor.blue
                strokeColor.setStroke()

                path.fill()
                path.stroke()
            }

错误:

2020-05-25 14:35:26.653308-0400 StatsApTBD[50679:10052723] [Unknown process name] CGContextSetFillColorWithColor: invalid context 0x0. Backtrace:
  <$s10StatsApTBD8HeatViewC08changeToD4MapsyyF10colorPathsL_yyF+94>
   <$s10StatsApTBD8HeatViewC08changeToD4MapsyyF+5247>
    <$s10StatsApTBD8HeatViewC8addMarksyyF+626>
     <$s10StatsApTBD8HeatViewC21viewDidLayoutSubviewsyyF+7831>
      <$s10StatsApTBD8HeatViewC21viewDidLayoutSubviewsyyFTo+43>
       <-[UIView(CALayerDelegate) layoutSublayersOfLayer:]+3013>
        <-[CALayer layoutSublayers]+255>
         <_ZN2CA5Layer16layout_if_neededEPNS_11TransactionE+517>
          <_ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE+80>
           <_ZN2CA7Context18commit_transactionEPNS_11TransactionEd+324>
            <_ZN2CA11Transaction6commitEv+643>
             <_afterCACommitHandler+160>
              <__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__+23>
               <__CFRunLoopDoObservers+430>
                <__CFRunLoopRun+1514>
                 <CFRunLoopRunSpecific+438>
                  <GSEventRunModal+65>
                   <UIApplicationMain+1621>
                    <main+75>
                     <start+1>                             1
2020-05-25 14:35:26.655966-0400 StatsApTBD[50679:10052723] [Unknown process name] CGContextSetStrokeColorWithColor: invalid context 0x0. Backtrace:
  <$s10StatsApTBD8HeatViewC08changeToD4MapsyyF10colorPathsL_yyF+175>
   <$s10StatsApTBD8HeatViewC08changeToD4MapsyyF+5247>
    <$s10StatsApTBD8HeatViewC8addMarksyyF+626>
     <$s10StatsApTBD8HeatViewC21viewDidLayoutSubviewsyyF+7831>
      <$s10StatsApTBD8HeatViewC21viewDidLayoutSubviewsyyFTo+43>
       <-[UIView(CALayerDelegate) layoutSublayersOfLayer:]+3013>
        <-[CALayer layoutSublayers]+255>
         <_ZN2CA5Layer16layout_if_neededEPNS_11TransactionE+517>
          <_ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE+80>
           <_ZN2CA7Context18commit_transactionEPNS_11TransactionEd+324>
            <_ZN2CA11Transaction6commitEv+643>
             <_afterCACommitHandler+160>
              <__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__+23>
               <__CFRunLoopDoObservers+430>
                <__CFRunLoopRun+1514>
                 <CFRunLoopRunSpecific+438>
                  <GSEventRunModal+65>
                   <UIApplicationMain+1621>
                    <main+75>
                     <start+1>                             1

【问题讨论】:

    标签: swift xcode uibezierpath


    【解决方案1】:

    创建一个 CAShapeLayer 并设置相同的路径,如下所示。

    let width: CGFloat = 200
    let height: CGFloat = 200
    
    let shapeLayer = CAShapeLayer()
    shapeLayer.frame = CGRect(x: 0, y: 0, width: width, height: height)
    
    let path = leftCorner
    shapeLayer.path = path
    shapeLayer.strokeColor = UIColor.blue.cgColor
    shapeLayer.fillColor = UIColor.white.cgColor
    

    然后将上面的 shapeLayer 添加到您的视图中。

    yourView.layer.addSublayer(shapeLayer)
    

    这应该会让你的路径显示在屏幕上。

    【讨论】:

    • 谢谢! addSubLayer sn-p 应该去哪里?在函数内,viewDidLoad 还是 subviewDidLoad?
    • 我不确定您在哪个函数中创建 shapeLayer/路径。如果您在 viewDidLoad 中执行此操作,则在创建 shapeLayer/路径后,将其添加到您的视图中。
    • 另外,XCode 强制解包“路径为!CGPath”,但后来我收到错误:线程 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    • 使用 leftCorner.cgPath。
    【解决方案2】:

    问题是您在视图控制器上绘图,但它应该在 UIView draw(_ rect: CGRect) 方法中完成。

    所以你需要继承一个 UIView,重写 draw 方法并在那里绘制你的贝塞尔路径:

    import UIKit
    
    class CanvasView: UIView {
        override func draw(_ rect: CGRect) {
            let bp = UIBezierPath(ovalIn: .init(origin: .zero, size: .init(width: 200, height: 200)))
            bp.lineWidth = 5
            UIColor.red.setFill()
            bp.fill()
            UIColor.yellow.setStroke()
            bp.stroke()
        }
    }
    

    现在您可以使用情节提要或以编程方式将 CanvasView 添加到视图控制器视图中:

    override func viewDidLoad() {
        super.viewDidLoad()
        let drawingView = CanvasView(frame: view.frame)
        view.addSubview(drawingView)
    }
    

    【讨论】:

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