[英]How I can create this circular shape in iOS Swift4?
我必須在UIView中創建如下圖所示的形狀。 但是我不知道如何繪制這種形狀。 我試圖使用帶有CAShapeLayer的UIBezierPath路徑成功繪制此形狀,但圓線繪制成功,但是我無法繪制圓點和圓形填充顏色。 任何人都可以建議我如何使用任何庫或UIBezierPath實現這種形狀。
這是我正在嘗試繪制此圓形的代碼。
class ViewController: UIViewController {
var firstButton = UIButton()
var mylabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
self.creatingLayerWithInformation()
}
func creatingLayerWithInformation(){
let safeAreaHeight = self.view.safeAreaInsets.top
let navBarHeight = self.navigationController?.navigationBar.frame.height
self.addLayer(isClockWise: true, radius: self.view.frame.width * 0.72, xPoint: 0, yPoint: navBarHeight!, layerColor: UIColor.green, fillcolor: .clear)
self.addLayer(isClockWise: true, radius: self.view.frame.width * 0.72, xPoint: self.view.frame.width, yPoint: self.view.frame.height - 150, layerColor: UIColor.blue, fillcolor: .clear)
let aa = self.view.frame.width * 0.72
self.addLayer(isClockWise: true, radius: 10, xPoint: 0+aa, yPoint: navBarHeight!+5, layerColor: UIColor.blue, fillcolor: .clear)
self.addLayer(isClockWise: true, radius: 10, xPoint: 0+15, yPoint: navBarHeight!+aa, layerColor: UIColor.blue, fillcolor: .clear)
}
func addLayer(isClockWise: Bool, radius: CGFloat, xPoint: CGFloat, yPoint: CGFloat, layerColor: UIColor, fillcolor: UIColor) {
let pi = CGFloat(Float.pi)
let start:CGFloat = 0.0
let end :CGFloat = 20
// circlecurve
let path: UIBezierPath = UIBezierPath();
path.addArc(
withCenter: CGPoint(x:xPoint, y:yPoint),
radius: (radius),
startAngle: start,
endAngle: end,
clockwise: isClockWise
)
let layer = CAShapeLayer()
layer.lineWidth = 3
layer.fillColor = fillcolor.cgColor
layer.strokeColor = layerColor.cgColor
layer.path = path.cgPath
self.view.layer.addSublayer(layer)
}}
但我得到以下結果。
請建議我如何實現這種形狀。 如果我做錯了什么,請糾正我。 如果有任何圖書館,也請提出建議。 請給我一些解決方案。
提前感謝大家。
有許多方法可以達到此效果,但是一個簡單的解決方案是不將大圓畫為單個弧,而是繪制為一系列在小圓的邊緣開始和停止的弧。 為此,您需要知道與內圓的偏移量。 做一點三角法,可以將其計算為:
let angleOffset = asin(innerRadius / 2 / mainRadius) * 2
從而:
let path = UIBezierPath()
path.move(to: point(from: arcCenter, radius: mainRadius, angle: startAngle))
let anglePerChoice = (endAngle - startAngle) / CGFloat(choices.count)
let angleOffset = asin(innerRadius / 2 / mainRadius) * 2
var from = startAngle
for index in 0 ..< choices.count {
var to = from + anglePerChoice / 2 - angleOffset
path.addArc(withCenter: arcCenter, radius: mainRadius, startAngle: from, endAngle: to, clockwise: true)
to = from + anglePerChoice
from += anglePerChoice / 2 + angleOffset
path.move(to: point(from: arcCenter, radius: mainRadius, angle: from))
path.addArc(withCenter: arcCenter, radius: mainRadius, startAngle: from, endAngle: to, clockwise: true)
from = to
}
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = strokeColor.cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = lineWidth
layer.addSublayer(shapeLayer)
哪里:
func point(from point: CGPoint, radius: CGFloat, angle: CGFloat) -> CGPoint {
return CGPoint(x: point.x + radius * cos(angle),
y: point.y + radius * sin(angle))
}
產生:
因此,當您添加內圓時:
盡管上面很簡單,但是它有局限性。 特別是,如果大弧線的lineWidth
與小圓弧的lineWidth
相比確實很寬,則單獨的大弧線的折線將無法與小圓弧的邊緣很好地對齊。 例如,想象小圓弧半徑為22點,但是大圓弧的筆划相對較寬,例如36點。
如果您有這種情況(不是您的情況,而是為了將來的讀者使用),如暗淡所建議的,另一種方法是將大圓弧繪制為單個筆觸,然后使用小圓圈的路徑對其進行遮罩。
因此,假設您有:
單個CAShapeLayer
,稱為mainArcLayer
,用於大弧; 和
所有小圓圈的UIBezierPath
數組,稱為smallCirclePaths
。
然后,您可以在UIView
子類的layoutSubviews
(或UIViewController
子類中的viewDidLayoutSubviews
中創建掩碼,如下所示:
override func layoutSubviews() {
super.layoutSubviews()
let path = UIBezierPath(rect: bounds)
smallCirclePaths.forEach { path.append($0) }
let mask = CAShapeLayer()
mask.fillColor = UIColor.white.cgColor
mask.strokeColor = UIColor.clear.cgColor
mask.lineWidth = 0
mask.path = path.cgPath
mask.fillRule = .evenOdd
mainArcLayer.mask = mask
}
產生:
這是對該問題的稍微更籠統的解決方案。
以最簡單的方式考慮問題。 想象一條直線,中間有一個小圓圈。
讓我們將思維分為三層:
需要顯示的背景
保持直線的層
包含小圓圈的圖層
計算小圓圈層相對於直線層的位置。
將小圓圈圖層放置在該位置。 好的,但是直線會顯示出來。
返回直線層。 給它戴上口罩 。 在小圓圈層的確切位置用透明圓圈構造該蒙版。
現在,遮罩沿着直線“打孔” —恰好是圓圈覆蓋的位置。 因此,我們似乎可以從圓環中看到背景,因為直線恰好在那個位置丟失了。
在現實生活中,將有多個圓形圖層,並且蒙版將具有多個透明圓形,並且直線將是一條曲線,但是一旦您完成了打孔操作,這將是一個小問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.