Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
350 views
in Technique[技术] by (71.8m points)

ios - Fill a UIView with diagonally drawn lines?

How to fill a UIView like this (with some diagonally drawn white lines).

enter image description here

PS: My intentions is about the fill not the border.

Any help?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One way of achieving this would be to override the draw(_:) method of UIView and do your custom drawing there.

Drawing diagonal lines is fairly simple, you just need to:

  • Stride from 0 to width + height (along the horizontal edge of the rect, then up the vertical), by the gap + line width, converted from being a diagonal (at 45o) length to being parallel to the edge of the rect to draw in.

  • At each iteration, draw a line from the given point for that iteration to the point on the edge opposite (at 45o). We get this point by simply working up the vertical edge of the rect, then along the horizontal)

Something like this should achieve the desired result:

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

Output:

enter image description here

(Assuming the view has a red backgroundColor)

You can adjust the lineGap and lineWidth properties to generate varying results.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...