2016-03-02 16 views

Antwort

11

Eine Möglichkeit, dies zu erreichen, wäre, die draw(_:) Methode von zu überschreiben und dort Ihre benutzerdefinierte Zeichnung zu erstellen.

diagonale Linien Zeichnung ist ziemlich einfach, man muss nur:

  • Stride von 0 bis Breite + Höhe (entlang der horizontalen Kante des rect, dann nach oben die vertikal), durch den Spalt + line Breite, umgewandelt, um ein diagonal entfernt, (bei 45 °) Länge parallel zum Rande des rect zu sein in.

  • bei jeder Iteration zu ziehen, für diese Iteration zu dem Punkt auf der Kante eine Linie vom vorgegebenen Punkt ziehen gegenüber (bei 45º). Wir bekommen diesen Punkt, indem Sie einfach arbeiten, um die vertikale Kante des rect auf, dann entlang der horizontalen)

So etwas sollte das gewünschte Ergebnis erzielen:

class StripeyView : UIView { 

    let lineGap: CGFloat = 7 
    let lineWidth: CGFloat = 3 
    let lineColor = UIColor.white 

    override func draw(_ rect: CGRect) { 

     let ctx = UIGraphicsGetCurrentContext()! 

     // flip y-axis of context, so (0,0) is the bottom left of the context 
     ctx.scaleBy(x: 1, y: -1) 
     ctx.translateBy(x: 0, y: -bounds.size.height) 

     // generate a slightly larger rect than the view, 
     // to allow the lines to appear seamless 
     let renderRect = bounds.insetBy(dx: -lineWidth * 0.5, dy: -lineWidth * 0.5) 

     // the total distance to travel when looping (each line starts at a point that 
     // starts at (0,0) and ends up at (width, height)). 
     let totalDistance = renderRect.size.width + renderRect.size.height 

     // loop through distances in the range 0 ... totalDistance 
     for distance in stride(from: 0, through: totalDistance, 
           // divide by cos(45º) to convert from diagonal length 
           by: (lineGap + lineWidth)/cos(.pi/4)) { 

      // the start of one of the stripes 
      ctx.move(to: CGPoint(
       // x-coordinate based on whether the distance is less than the width of the 
       // rect (it should be fixed if it is above, and moving if it is below) 
       x: distance < renderRect.width ? 
        renderRect.origin.x + distance : 
        renderRect.origin.x + renderRect.width, 

       // y-coordinate based on whether the distance is less than the width of the 
       // rect (it should be moving if it is above, and fixed if below) 
       y: distance < renderRect.width ? 
        renderRect.origin.y : 
        distance - (renderRect.width - renderRect.origin.x) 
      )) 

      // the end of one of the stripes 
      ctx.addLine(to: CGPoint(
       // x-coordinate based on whether the distance is less than the height of 
       // the rect (it should be moving if it is above, and fixed if it is below) 
       x: distance < renderRect.height ? 
        renderRect.origin.x : 
        distance - (renderRect.height - renderRect.origin.y), 

       // y-coordinate based on whether the distance is less than the height of 
       // the rect (it should be fixed if it is above, and moving if it is below) 
       y: distance < renderRect.height ? 
        renderRect.origin.y + distance : 
        renderRect.origin.y + renderRect.height 
      )) 
     } 

     // stroke all of the lines added 
     ctx.setStrokeColor(lineColor.cgColor) 
     ctx.setLineWidth(lineWidth) 
     ctx.strokePath() 
    } 
} 

Ausgang:

enter image description here

(die Ansicht Unter der Annahme, hat eine rote backgroundColor)

Sie können die Eigenschaften lineGap und lineWidth anpassen, um unterschiedliche Ergebnisse zu erzielen.

+0

Danke und ich wirklich zu schätzen Ihre Erklärung über Ihre Antwort. – Goppinath

+0

@Goppinath glücklich zu helfen! :) – Hamish

-3

Der einfachste Weg für mich ist, ein Hintergrundbild in Ihre UIView (like this) zu legen. Die zweite Lösung besteht darin, die Linien mit Core Graphics Framework zu zeichnen (effizienter, aber mehr Code zum Schreiben).

Hoffe diese Hilfe!

7

Erstaunlicher einfachen Algorithmus ...

Sagen Sie bitte diese Werte haben ...

let T: CGFloat = 15  // desired thickness of lines 
    let G: CGFloat = 30  // desired gap between lines 
    let W = rect.size.width 
    let H = rect.size.height 

erstaunlich, es ist so einfach ...

var p = -(W > H ? W : H) - T 
    while p <= W { 

     c.move(to: CGPoint(x: p-T, y: -T)) 
     c.addLine(to: CGPoint(x: p+T+H, y: T+H)) 
     c.strokePath() 
     p += G + T + T 
    } 

enter image description here

Hier ist eine vollständige UIView-Klasse:

class Ruled: UIView { 

    override func draw(_ rect: CGRect) { 

     let T: CGFloat = 15  // desired thickness of lines 
     let G: CGFloat = 30  // desired gap between lines 
     let W = rect.size.width 
     let H = rect.size.height 

     guard let c = UIGraphicsGetCurrentContext() else { return } 
     c.setStrokeColor(UIColor.orange.cgColor) 
     c.setLineWidth(T) 

     var p = -(W > H ? W : H) - T 
     while p <= W { 

      c.move(to: CGPoint(x: p-T, y: -T)) 
      c.addLine(to: CGPoint(x: p+T+H, y: T+H)) 
      c.strokePath() 
      p += G + T + T 
     } 
    } 
} 

Das war's!

Der gesamte grundlegende Algorithmus:

1. Start an der oberen linken Ecke, minus die längste Seite

2. Zieh Diagonalen, bis ihr nach rechts

Nizza und einfach! :)


zu einem Rechteck befestigen:

Die Klasse oben einfach zieht die „Größe des UIView“. Oft möchten Sie eine Anzahl der "Kästchen" tatsächlich in der Ansicht an verschiedenen Koordinaten zeichnen. (Ein gutes Beispiel ist für einen Kalender).

enter image description here

Darüber hinaus dieses Beispiel zieht ausdrücklich „die beiden Streifen“ eher als ein Streifen über die Hintergrundfarbe zeichnen:

func simpleStripes(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) { 

    let stripeWidth: CGFloat = 20.0 // whatever you want 
    let m = stripeWidth/2.0 

    guard let c = UIGraphicsGetCurrentContext() else { return } 
    c.setLineWidth(stripeWidth) 

    let r = CGRect(x: x, y: y, width: width, height: height) 
    let longerSide = width > height ? width : height 

    c.saveGState() 
    c.clip(to: r) 

     var p = x - longerSide 
     while p <= x + width { 

      c.setStrokeColor(pale blue) 
      c.move(to: CGPoint(x: p-m, y: y-m)) 
      c.addLine(to: CGPoint(x: p+m+height, y: y+m+height)) 
      c.strokePath() 

      p += stripeWidth 

      c.setStrokeColor(pale gray) 
      c.move(to: CGPoint(x: p-m, y: y-m)) 
      c.addLine(to: CGPoint(x: p+m+height, y: y+m+height)) 
      c.strokePath() 

      p += stripeWidth 
     } 

    c.restoreGState() 
} 

Wenn Sie animieren möchten bewegen sie ...

1, Offset, einfach aus dem Zeiger subtrahieren, wenn Sie es starten. Erstaunlicherweise muss nichts anderes geändert werden.

var p = x - longerSide - offset // animate offset from 0 to stripeWidth 

2, würden Sorgfältige Programmierer einen gleich die Gehrung Offset bevorzugen das "spitze obere linke Ecke" Problem zu vermeiden:

var p = x - longerSide - offset - m // for better-looking top-left corner 

enter image description here

3, Sie verwenden können eine beliebige Anzahl von Streifen in verschiedenen Farben, und in der Tat kann man unterschiedliche Streifenbreiten in einer beliebigen Kombination verwendet werden. Erstaunlicherweise funktioniert der Algorithmus immer noch und ist sicher. (Wenn Sie mehr als eine Breite haben, stellen nur die Mitra m als die maximale Breite.)

+0

danke nochmal und es wird sehr schön mit Beispielen erklärt. Danke noch einmal! – Goppinath

+0

genießen, @Goppinath! – Fattie

+0

Aber was ist der Punkt, der die Prämie zu öffnen und die gleiche Frage @Fattie zu beantworten? – Goppinath

Verwandte Themen