如何用 Swift 填充 UIBezierPath 的内部?
How can I fill the inside of a UIBezierPath with Swift?
我正在尝试使用 Swift 5 填充 UIBezierPath,但是当我尝试 运行 我的函数为路径着色时,出现了很多错误。 None 其中是致命的,因此构建成功,但路径未绘制在屏幕上。我附上相关代码和两个错误。提前致谢。
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
创建一个 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)
这应该让您的路径显示在屏幕上。
问题是您在视图控制器上绘图,但它应该在 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)
}
我正在尝试使用 Swift 5 填充 UIBezierPath,但是当我尝试 运行 我的函数为路径着色时,出现了很多错误。 None 其中是致命的,因此构建成功,但路径未绘制在屏幕上。我附上相关代码和两个错误。提前致谢。
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
创建一个 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)
这应该让您的路径显示在屏幕上。
问题是您在视图控制器上绘图,但它应该在 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)
}