2016-03-02 84 views

回答

11

實現此目的的一種方法是重寫draw(_:)方法UIView並在那裏進行自定義繪圖。

繪製對角線是相當簡單的,你只需要:

  • 步幅從0到寬度+高度(沿所述矩形的水平邊緣,然後向上垂直),由間隙+線寬度,從對角線(在45º)長度轉換爲平行於矩形的邊緣繪製。

  • 在每次迭代中,從該迭代的給定點繪製一條直線到邊緣上的點對面(45º)。

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

    輸出:

    我們通過簡單的處理,將矩形的垂直邊緣,然後沿水平)

像這樣的事情應該達到預期的效果得到了這一點(假設視圖有紅色backgroundColor

您可以調整lineGaplineWidth屬性以生成不同的結果。

+0

謝謝,我非常感謝您的解釋,而不是您的回答。 – Goppinath

+0

@Goppinath樂意幫忙! :) – Hamish

-3

對我來說最簡單的方法是在你的UIView(like this)中放置一個背景圖片。第二種解決方案是使用Core Graphics Framework繪製線條(更高效,但需要編寫更多代碼)。

希望得到這個幫助!

7

令人驚訝的是簡單的算法...

說你有這些價值觀......

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 

令人驚訝的話,那就是簡單...

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

這裏是一個完整的UIView類:

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

就是這樣!

整個基本算法:在左上角,

1.啓動減去最長邊

2.抽獎對角線,直到你來對了

尼斯和容易! :)


夾到一個矩形:

類上面簡單地繪製它的「了UIView的大小」。通常,您想要在不同的座標中實際繪製一些「框」。 (一個很好的例子是日曆)。

enter image description here

此外,本例中明確地得出「兩條紋」,而不是在背景色繪製一個條:

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

如果要動畫將它們移動...

1,要進行偏移,只需在啓動時從指針中減去。令人驚訝的是,沒有別的東西需要改變。

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

2,細心的程序員會喜歡的偏移等於斜切避免了 「尖左上角」 的問題:

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

enter image description here

3,您可以使用各種顏色的任何條紋,事實上,你可以使用不同的條紋寬度在任何組合。令人驚訝的是,該算法仍然有效並且安全。 (如果您有多個寬度,只需將斜角m設置爲最大寬度。)

+0

再次感謝,並用實例很好地解釋。再次感謝! – Goppinath

+0

享受,@Goppinath! – Fattie

+0

但是打開賞金並回答同一個問題@Fattie的意義何在? – Goppinath