在 Swift 2/3 中对称设置 LineDash
setLineDash symmetrically in Swift 2/3
我正在开发一个网速测试应用程序。我会做一些事情来练习和了解更多关于未来项目的信息。
这是我的Swift代码:
import UIKit
@IBDesignable
class Arc: UIView {
@IBInspectable var dashWidth: CGFloat = 12.0
@IBInspectable var smallDashWidth: CGFloat = 5.0
override func draw(_ rect: CGRect) {
// Position and Radius of Arc
let center = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
// Calculate Angles
let π = CGFloat(M_PI)
let startAngle = 3 * π / 4
let endAngle = π / 4
let radius = max(bounds.width / 1.15, bounds.height / 1.15) / 2 - dashWidth / 2
// Start Context
let context = UIGraphicsGetCurrentContext()
// MARK: Base
let arc = UIBezierPath(arcCenter: center, radius: radius,startAngle: startAngle,endAngle: endAngle,clockwise: true)
arc.addArc(withCenter: center, radius: radius, startAngle: endAngle, endAngle: startAngle, clockwise: false)
arc.lineJoinStyle = .bevel
arc.lineCapStyle = .round
arc.close()
UIColor.yellow().setStroke()
arc.lineWidth = smallDashWidth
//context!.saveGState()
context!.setLineDash(phase: 0, lengths: [0, 0], count: 2)
arc.stroke()
context!.saveGState()
// MARK: dash Arc
let dashArc = UIBezierPath()
dashArc.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
// Round Line
dashArc.lineJoinStyle = .round;
// Set Stroke and Width of Dash
UIColor.white().setStroke()
dashArc.lineWidth = dashWidth
// Save Context and Set Line Dash
context!.saveGState()
context!.setLineDash(phase: 0, lengths: [2, 54], count: 2)
// Draw Line
dashArc.stroke()
// Restore Context
context!.restoreGState()
}
}
结果是这样的:
我需要做的事情:
我需要自动化这行代码:
context!.setLineDash(phase: 0, lengths: [2, 54], count: 2)
长度是[2, 54],这些数字是相加的,没有计算,只是为了得到最终的方程数,动态地得到这个。
1:需要在圆弧上加上破折号12(以后可能会改变,作为变量赋值)。圆弧以可变角度开始和结束(以后可以更改)。
2:dashArc.lineWidth = dashWidth
的值也是可以改变的,是计算12个破折号之间space的重要项目。
3:由于所有变量呈现的值都可以是可变的,这是进行这种计算的最佳方式。
4: 第一个和最后一个破折号应该与相应的 startAngle 和 endAngle 成相同的角度。
我需要的:
我需要一个计算,使弧线中的破折号看起来和分布尽可能对称。
我想到了一个类似的计算:
var numberOfDashes = 12
var perimeterArc = ?
var widthDash = 2
spacing = (perimeterArc - (widthDash * numberOfDashes)) / numberOfDashes
context!.setLineDash(phase: 0, lengths: [widthDash, spacing], count: 2)
但是我不知道如何计算perimeterArc。
有人能帮我吗?在 Swift 2/3.
中,我想不出任何可以为此创建逻辑计算的东西
感谢任何提示。
与其尝试使用破折号模式直接计算空间,不如首先考虑角度。
我提取了一些代码,这些代码最初是在我的 PostScript By Example 一书中作为示例创建的(第 281 页)。我将后记代码音译为 Swift(版本 2,因为版本 3 似乎不能做任何有用的事情)。
我还避免将 UIBezierPath 与对图形上下文的访问混合使用,因为我觉得两者之间存在一些奇怪的交互。 UIBezierPath 旨在管理幕后的图形上下文。
代码如下:
class ComputeDashes : UIView
{
让 insetAmount: CGFloat = 40.0
let numberOfDashes: Int = 16
let startAngle: CGFloat = CGFloat(1.0 * M_PI / 4.0)
let endAngle: CGFloat = CGFloat(3.0 * M_PI / 4.0)
let subtendedAngle: CGFloat = CGFloat(2.0 * M_PI) - CGFloat(2.0 * M_PI / 4.0)
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder: NSCoder) {
super.init(coder: coder)!
}
override func drawRect(rect: CGRect)
{
let insets: UIEdgeInsets = UIEdgeInsetsMake(insetAmount, insetAmount, insetAmount, insetAmount)
let newbounds: CGRect = UIEdgeInsetsInsetRect(self.bounds, insets)
let centre: CGPoint = CGPointMake(CGRectGetMidX(newbounds), CGRectGetMidY(newbounds))
let radius: CGFloat = CGRectGetWidth(newbounds) / 2.0
let context: CGContext = UIGraphicsGetCurrentContext()!
CGContextAddArc(context, centre.x, centre.y, radius, startAngle, endAngle, 1)
CGContextSetLineWidth(context, 10.0)
UIColor.magentaColor().set()
CGContextStrokePath(context)
// MARK: paint dashes
let innerRadius: CGFloat = radius * 0.75
CGContextSaveGState(context)
CGContextTranslateCTM(context, centre.x, centre.y)
let angle = subtendedAngle / CGFloat(numberOfDashes)
CGContextRotateCTM(context, endAngle)
for rot in 0...numberOfDashes {
let innerPoint: CGPoint = CGPointMake(innerRadius, 0.0)
CGContextMoveToPoint(context, innerPoint.x, innerPoint.y)
let outerPoint: CGPoint = CGPointMake(radius, 0.0)
CGContextAddLineToPoint(context, outerPoint.x, outerPoint.y)
CGContextRotateCTM(context, angle)
}
CGContextSetLineWidth(context, 2.0)
UIColor.blackColor().set()
CGContextStrokePath(context)
CGContextRestoreGState(context)
}
}
我相信这种方法更加灵活,并且避免了在虚线图案的 'on' 阶段考虑线宽时需要进行的棘手计算。
希望对您有所帮助。让我知道你的想法。
我正在开发一个网速测试应用程序。我会做一些事情来练习和了解更多关于未来项目的信息。
这是我的Swift代码:
import UIKit
@IBDesignable
class Arc: UIView {
@IBInspectable var dashWidth: CGFloat = 12.0
@IBInspectable var smallDashWidth: CGFloat = 5.0
override func draw(_ rect: CGRect) {
// Position and Radius of Arc
let center = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
// Calculate Angles
let π = CGFloat(M_PI)
let startAngle = 3 * π / 4
let endAngle = π / 4
let radius = max(bounds.width / 1.15, bounds.height / 1.15) / 2 - dashWidth / 2
// Start Context
let context = UIGraphicsGetCurrentContext()
// MARK: Base
let arc = UIBezierPath(arcCenter: center, radius: radius,startAngle: startAngle,endAngle: endAngle,clockwise: true)
arc.addArc(withCenter: center, radius: radius, startAngle: endAngle, endAngle: startAngle, clockwise: false)
arc.lineJoinStyle = .bevel
arc.lineCapStyle = .round
arc.close()
UIColor.yellow().setStroke()
arc.lineWidth = smallDashWidth
//context!.saveGState()
context!.setLineDash(phase: 0, lengths: [0, 0], count: 2)
arc.stroke()
context!.saveGState()
// MARK: dash Arc
let dashArc = UIBezierPath()
dashArc.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
// Round Line
dashArc.lineJoinStyle = .round;
// Set Stroke and Width of Dash
UIColor.white().setStroke()
dashArc.lineWidth = dashWidth
// Save Context and Set Line Dash
context!.saveGState()
context!.setLineDash(phase: 0, lengths: [2, 54], count: 2)
// Draw Line
dashArc.stroke()
// Restore Context
context!.restoreGState()
}
}
结果是这样的:
我需要做的事情:
我需要自动化这行代码:
context!.setLineDash(phase: 0, lengths: [2, 54], count: 2)
长度是[2, 54],这些数字是相加的,没有计算,只是为了得到最终的方程数,动态地得到这个。
1:需要在圆弧上加上破折号12(以后可能会改变,作为变量赋值)。圆弧以可变角度开始和结束(以后可以更改)。
2:dashArc.lineWidth = dashWidth
的值也是可以改变的,是计算12个破折号之间space的重要项目。
3:由于所有变量呈现的值都可以是可变的,这是进行这种计算的最佳方式。
4: 第一个和最后一个破折号应该与相应的 startAngle 和 endAngle 成相同的角度。
我需要的:
我需要一个计算,使弧线中的破折号看起来和分布尽可能对称。
我想到了一个类似的计算:
var numberOfDashes = 12
var perimeterArc = ?
var widthDash = 2
spacing = (perimeterArc - (widthDash * numberOfDashes)) / numberOfDashes
context!.setLineDash(phase: 0, lengths: [widthDash, spacing], count: 2)
但是我不知道如何计算perimeterArc。 有人能帮我吗?在 Swift 2/3.
中,我想不出任何可以为此创建逻辑计算的东西感谢任何提示。
与其尝试使用破折号模式直接计算空间,不如首先考虑角度。
我提取了一些代码,这些代码最初是在我的 PostScript By Example 一书中作为示例创建的(第 281 页)。我将后记代码音译为 Swift(版本 2,因为版本 3 似乎不能做任何有用的事情)。
我还避免将 UIBezierPath 与对图形上下文的访问混合使用,因为我觉得两者之间存在一些奇怪的交互。 UIBezierPath 旨在管理幕后的图形上下文。
代码如下:
class ComputeDashes : UIView
{
让 insetAmount: CGFloat = 40.0
let numberOfDashes: Int = 16
let startAngle: CGFloat = CGFloat(1.0 * M_PI / 4.0)
let endAngle: CGFloat = CGFloat(3.0 * M_PI / 4.0)
let subtendedAngle: CGFloat = CGFloat(2.0 * M_PI) - CGFloat(2.0 * M_PI / 4.0)
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder: NSCoder) {
super.init(coder: coder)!
}
override func drawRect(rect: CGRect)
{
let insets: UIEdgeInsets = UIEdgeInsetsMake(insetAmount, insetAmount, insetAmount, insetAmount)
let newbounds: CGRect = UIEdgeInsetsInsetRect(self.bounds, insets)
let centre: CGPoint = CGPointMake(CGRectGetMidX(newbounds), CGRectGetMidY(newbounds))
let radius: CGFloat = CGRectGetWidth(newbounds) / 2.0
let context: CGContext = UIGraphicsGetCurrentContext()!
CGContextAddArc(context, centre.x, centre.y, radius, startAngle, endAngle, 1)
CGContextSetLineWidth(context, 10.0)
UIColor.magentaColor().set()
CGContextStrokePath(context)
// MARK: paint dashes
let innerRadius: CGFloat = radius * 0.75
CGContextSaveGState(context)
CGContextTranslateCTM(context, centre.x, centre.y)
let angle = subtendedAngle / CGFloat(numberOfDashes)
CGContextRotateCTM(context, endAngle)
for rot in 0...numberOfDashes {
let innerPoint: CGPoint = CGPointMake(innerRadius, 0.0)
CGContextMoveToPoint(context, innerPoint.x, innerPoint.y)
let outerPoint: CGPoint = CGPointMake(radius, 0.0)
CGContextAddLineToPoint(context, outerPoint.x, outerPoint.y)
CGContextRotateCTM(context, angle)
}
CGContextSetLineWidth(context, 2.0)
UIColor.blackColor().set()
CGContextStrokePath(context)
CGContextRestoreGState(context)
}
}
我相信这种方法更加灵活,并且避免了在虚线图案的 'on' 阶段考虑线宽时需要进行的棘手计算。
希望对您有所帮助。让我知道你的想法。