Swift 向圆形添加方形破折号
Swift Add square dashes to Circle
我有一个自定义视图 class,它画了一个圆,如下所示:
import UIKit
@IBDesignable
class RotaryCircleSlider:UIView
{
@IBInspectable var mainColor: UIColor = UIColor.blue
{
didSet { print("mainColor was set here") }
}
@IBInspectable var ringColor: UIColor = UIColor.orange
{
didSet { print("bColor was set here") }
}
@IBInspectable var ringThickness: CGFloat = 4
{
didSet { print("ringThickness was set here") }
}
@IBInspectable var isSelected: Bool = true
override func draw(_ rect: CGRect)
{
let dotPath = UIBezierPath(ovalIn:rect)
let shapeLayer = CAShapeLayer()
shapeLayer.path = dotPath.cgPath
shapeLayer.fillColor = mainColor.cgColor
layer.addSublayer(shapeLayer)
if (isSelected) { drawRingFittingInsideView(rect: rect) }
}
internal func drawRingFittingInsideView(rect: CGRect)->()
{
let hw:CGFloat = ringThickness/2
let circlePath = UIBezierPath(ovalIn: rect.insetBy(dx: hw,dy: hw) )
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = ringColor.cgColor
shapeLayer.lineWidth = ringThickness
layer.addSublayer(shapeLayer)
}
}
但是我希望圆形视图像时钟一样被分割。
虽然,我试过linecap和lineDashPattern,但我无法得到它。
这是创建您想要的视图的代码...您可以根据您的设计更改它们
import Foundation
import UIKit
@IBDesignable
class RotaryCircleSlider:UIView
{
@IBInspectable var mainColor: UIColor = #colorLiteral(red: 0.1999788582, green: 0.2000134587, blue: 0.1999712586, alpha: 1)
{
didSet { print("mainColor was set here") }
}
@IBInspectable var ringColor: UIColor = #colorLiteral(red: 0.7466413379, green: 0.027390128, blue: 0.2014107406, alpha: 1)
{
didSet { print("bColor was set here") }
}
@IBInspectable var ringThickness: CGFloat = 14
{
didSet { print("ringThickness was set here") }
}
@IBInspectable var isSelected: Bool = true
override func draw(_ rect: CGRect)
{
let dotPath = UIBezierPath(ovalIn:rect)
let shapeLayer = CAShapeLayer()
shapeLayer.path = dotPath.cgPath
shapeLayer.fillColor = mainColor.cgColor
layer.addSublayer(shapeLayer)
let ringView = RingProgressHud(frame: rect)
drawRingFittingInsideView(rect: rect)
addSubview(ringView)
let stack = UIStackView(frame: CGRect(x: 0, y: 0, width: rect.width * 0.4, height: rect.width * 0.4))
stack.alignment = .center
stack.axis = .vertical
stack.center = CGPoint(x: bounds.midX, y: bounds.midY)
stack.distribution = .fillProportionally
addSubview(stack)
let label = UILabel()
label.text = "172"
label.font = .systemFont(ofSize: 30, weight: .heavy)
label.sizeToFit()
label.textColor = .white
let move = UILabel()
move.text = "Total Move"
move.font = .systemFont(ofSize: 15, weight: .regular)
move.sizeToFit()
move.textColor = #colorLiteral(red: 0.5293634534, green: 0.5294427276, blue: 0.529346168, alpha: 1)
let ccw = UILabel()
ccw.text = "CCW"
ccw.font = .systemFont(ofSize: 18, weight: .semibold)
ccw.sizeToFit()
ccw.textColor = .white
let direction = UILabel()
direction.text = "Active Direction"
direction.font = .systemFont(ofSize: 14, weight: .regular)
direction.sizeToFit()
direction.textColor = #colorLiteral(red: 0.5293634534, green: 0.5294427276, blue: 0.529346168, alpha: 1)
stack.addArrangedSubview(label)
stack.addArrangedSubview(move)
stack.addArrangedSubview(ccw)
stack.addArrangedSubview(direction)
}
internal func drawRingFittingInsideView(rect: CGRect)->()
{
let hw:CGFloat = ringThickness/2
let circlePath = UIBezierPath(ovalIn: rect.insetBy(dx: hw,dy: hw) )
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = ringColor.cgColor
shapeLayer.lineWidth = ringThickness
layer.addSublayer(shapeLayer)
}
}
和其他 class 创建时钟形状条在此处
import UIKit
@IBDesignable
class RingProgressHud : UIView {
let numberOfTeeth = UInt(60) // Number of teetch to render
let teethSize = CGSize(width:2, height:15) // The size of each individual tooth
let shapeLayer = CAShapeLayer() // The teeth shape layer
private func getPathMask(size:CGSize, teethCount:UInt, teethSize:CGSize, radius:CGFloat) -> CGPath? {
let halfHeight = size.height*0.5
let halfWidth = size.width*0.5
let deltaAngle = CGFloat(2*Double.pi)/CGFloat(teethCount); // The change in angle between paths
// Create the template path of a single shape.
let p = CGPath(rect: CGRect(x: -teethSize.width*0.5, y: radius, width: teethSize.width, height: teethSize.height), transform: nil)
let returnPath = CGMutablePath()
for i in 0..<teethCount { // Copy, translate and rotate shapes around
let translate = CGAffineTransform(translationX: halfWidth, y: halfHeight)
let rotate = translate.rotated(by: deltaAngle*CGFloat(i))
returnPath.addPath(p, transform: rotate)
}
return returnPath.copy()
}
private func commonSetup() {
shapeLayer.path = getPathMask(size: frame.size, teethCount: numberOfTeeth, teethSize: teethSize, radius: ((frame.width*0.4)-teethSize.height))
shapeLayer.fillColor = #colorLiteral(red: 0.3411435485, green: 0.3411974311, blue: 0.341131866, alpha: 1)
layer.addSublayer(shapeLayer)
}
override init(frame: CGRect) {
super.init(frame: frame)
commonSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonSetup()
}
}
我也在 git 上添加了它们...您也可以从那里下载它们
我有一个自定义视图 class,它画了一个圆,如下所示:
import UIKit
@IBDesignable
class RotaryCircleSlider:UIView
{
@IBInspectable var mainColor: UIColor = UIColor.blue
{
didSet { print("mainColor was set here") }
}
@IBInspectable var ringColor: UIColor = UIColor.orange
{
didSet { print("bColor was set here") }
}
@IBInspectable var ringThickness: CGFloat = 4
{
didSet { print("ringThickness was set here") }
}
@IBInspectable var isSelected: Bool = true
override func draw(_ rect: CGRect)
{
let dotPath = UIBezierPath(ovalIn:rect)
let shapeLayer = CAShapeLayer()
shapeLayer.path = dotPath.cgPath
shapeLayer.fillColor = mainColor.cgColor
layer.addSublayer(shapeLayer)
if (isSelected) { drawRingFittingInsideView(rect: rect) }
}
internal func drawRingFittingInsideView(rect: CGRect)->()
{
let hw:CGFloat = ringThickness/2
let circlePath = UIBezierPath(ovalIn: rect.insetBy(dx: hw,dy: hw) )
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = ringColor.cgColor
shapeLayer.lineWidth = ringThickness
layer.addSublayer(shapeLayer)
}
}
但是我希望圆形视图像时钟一样被分割。
虽然,我试过linecap和lineDashPattern,但我无法得到它。
这是创建您想要的视图的代码...您可以根据您的设计更改它们
import Foundation
import UIKit
@IBDesignable
class RotaryCircleSlider:UIView
{
@IBInspectable var mainColor: UIColor = #colorLiteral(red: 0.1999788582, green: 0.2000134587, blue: 0.1999712586, alpha: 1)
{
didSet { print("mainColor was set here") }
}
@IBInspectable var ringColor: UIColor = #colorLiteral(red: 0.7466413379, green: 0.027390128, blue: 0.2014107406, alpha: 1)
{
didSet { print("bColor was set here") }
}
@IBInspectable var ringThickness: CGFloat = 14
{
didSet { print("ringThickness was set here") }
}
@IBInspectable var isSelected: Bool = true
override func draw(_ rect: CGRect)
{
let dotPath = UIBezierPath(ovalIn:rect)
let shapeLayer = CAShapeLayer()
shapeLayer.path = dotPath.cgPath
shapeLayer.fillColor = mainColor.cgColor
layer.addSublayer(shapeLayer)
let ringView = RingProgressHud(frame: rect)
drawRingFittingInsideView(rect: rect)
addSubview(ringView)
let stack = UIStackView(frame: CGRect(x: 0, y: 0, width: rect.width * 0.4, height: rect.width * 0.4))
stack.alignment = .center
stack.axis = .vertical
stack.center = CGPoint(x: bounds.midX, y: bounds.midY)
stack.distribution = .fillProportionally
addSubview(stack)
let label = UILabel()
label.text = "172"
label.font = .systemFont(ofSize: 30, weight: .heavy)
label.sizeToFit()
label.textColor = .white
let move = UILabel()
move.text = "Total Move"
move.font = .systemFont(ofSize: 15, weight: .regular)
move.sizeToFit()
move.textColor = #colorLiteral(red: 0.5293634534, green: 0.5294427276, blue: 0.529346168, alpha: 1)
let ccw = UILabel()
ccw.text = "CCW"
ccw.font = .systemFont(ofSize: 18, weight: .semibold)
ccw.sizeToFit()
ccw.textColor = .white
let direction = UILabel()
direction.text = "Active Direction"
direction.font = .systemFont(ofSize: 14, weight: .regular)
direction.sizeToFit()
direction.textColor = #colorLiteral(red: 0.5293634534, green: 0.5294427276, blue: 0.529346168, alpha: 1)
stack.addArrangedSubview(label)
stack.addArrangedSubview(move)
stack.addArrangedSubview(ccw)
stack.addArrangedSubview(direction)
}
internal func drawRingFittingInsideView(rect: CGRect)->()
{
let hw:CGFloat = ringThickness/2
let circlePath = UIBezierPath(ovalIn: rect.insetBy(dx: hw,dy: hw) )
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = ringColor.cgColor
shapeLayer.lineWidth = ringThickness
layer.addSublayer(shapeLayer)
}
}
和其他 class 创建时钟形状条在此处
import UIKit
@IBDesignable
class RingProgressHud : UIView {
let numberOfTeeth = UInt(60) // Number of teetch to render
let teethSize = CGSize(width:2, height:15) // The size of each individual tooth
let shapeLayer = CAShapeLayer() // The teeth shape layer
private func getPathMask(size:CGSize, teethCount:UInt, teethSize:CGSize, radius:CGFloat) -> CGPath? {
let halfHeight = size.height*0.5
let halfWidth = size.width*0.5
let deltaAngle = CGFloat(2*Double.pi)/CGFloat(teethCount); // The change in angle between paths
// Create the template path of a single shape.
let p = CGPath(rect: CGRect(x: -teethSize.width*0.5, y: radius, width: teethSize.width, height: teethSize.height), transform: nil)
let returnPath = CGMutablePath()
for i in 0..<teethCount { // Copy, translate and rotate shapes around
let translate = CGAffineTransform(translationX: halfWidth, y: halfHeight)
let rotate = translate.rotated(by: deltaAngle*CGFloat(i))
returnPath.addPath(p, transform: rotate)
}
return returnPath.copy()
}
private func commonSetup() {
shapeLayer.path = getPathMask(size: frame.size, teethCount: numberOfTeeth, teethSize: teethSize, radius: ((frame.width*0.4)-teethSize.height))
shapeLayer.fillColor = #colorLiteral(red: 0.3411435485, green: 0.3411974311, blue: 0.341131866, alpha: 1)
layer.addSublayer(shapeLayer)
}
override init(frame: CGRect) {
super.init(frame: frame)
commonSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonSetup()
}
}
我也在 git 上添加了它们...您也可以从那里下载它们