2016-07-27 2 views
1

인터넷 속도 테스트 앱을 개발 중입니다. 미래의 프로젝트에 대해 더 연습하고 배우기 위해 할 일.setLineDash 대칭 Swift 2/3에

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() 
    } 

} 

결과는 이것이다 :

이 내 스위프트 코드입니다

을 내가 자동화해야 내가해야 할 일은


enter image description here 이 코드 란 :

context!.setLineDash(phase: 0, lengths: [2, 54], count: 2) 

길이는 [2, 54]이며, 숫자는 계산없이 추가되며이 공식을 얻기 위해 최종 방정식 번호를 얻는 데에만 사용됩니다. 1 : 대시 12 (나중에 변수로 할당 될 수 있음)를 호 전체에 추가해야합니다. 호는 가변 각도로 시작하고 끝납니다 (나중에 변경할 수 있음). 2 : dashArc.lineWidth = dashWidth의 값도 변경할 수 있으며 12 개의 대시 사이의 공백을 계산하는 데 중요한 항목입니다. 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을 계산하는 방법을 모르겠어요. 누군가 나를 도울 수 있습니까? 스위프트 2/3에서 이것에 대한 논리적 인 계산을 만들 수있는 어떤 것도 생각할 수 없었습니다.

나는 어떤 조언을 주셔서 감사합니다.

답변

2

대시 패턴을 사용하여 직접 공백을 계산하려고 시도하는 대신, 우선 각도로 생각하십시오.

예를 들어 제 PostScript By Example (281 페이지)에 예제로 작성된 일부 코드를 들었습니다. 나는 포스트 스크립트 코드를 Swift로 번역했다 (버전 2는 버전 3이 유용하지는 못하다).

그래픽 컨텍스트에 대한 액세스로 혼합 된 UIBezierPath 사용을 피했습니다. 두 인터페이스 사이에 이상한 상호 작용이 있다는 느낌이 들었 기 때문에. UIBezierPath는 그래픽 컨텍스트를 관리하기위한 것입니다.{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) 
} 

}

class ComputeDashes : UIView 

: 여기

코드입니다

나는이 방법이 훨씬 더 유연하다고 생각

및 '선의 너비를 고려하기 위해해야 ​​할 까다로운 계산을 피합니다. 대쉬 패턴의 n '위상.

이 정보가 도움이되기를 바랍니다. 당신이 무슨 생각을하는지 제게 알려주세요.

+0

감사합니다. 내가 필요한 것! – James