Search code examples
swiftcore-graphics

Drawing a dotted background in swift


Im trying to achieve a dotted view that I can use as a background. Something looking a bit like this: Image showing dotted background

But I seem to be missing something in my code. I have tried to lab around with different sizes of the dots and everything, but so far I'm just getting my background color set to the view but no dots no matter the size, the color or the spacing. What am I missing?

class DottedBackgroundView: UIView {

override func draw(_ rect: CGRect) {
    guard let context = UIGraphicsGetCurrentContext() else { return }
    UIColor.green.setFill()
    context.fill(rect)

    let drawPattern: CGPatternDrawPatternCallback = { _, context in
        context.addArc(
            center: CGPoint(x: 5, y: 5), radius: 2.5,
            startAngle: 0, endAngle: CGFloat(2.0 * .pi),
            clockwise: false)
        context.setFillColor(UIColor.white.cgColor)
        context.fillPath()
    }

    var callbacks = CGPatternCallbacks(
        version: 0, drawPattern: drawPattern, releaseInfo: nil)

    let pattern = CGPattern(
        info: nil,
        bounds: CGRect(x: 0, y: 0, width: 10, height: 10),
        matrix: .identity,
        xStep: 10,
        yStep: 10,
        tiling: .constantSpacing,
        isColored: true,
        callbacks: &callbacks)

    let patternSpace = CGColorSpace(patternBaseSpace: nil)!
    context.setFillColorSpace(patternSpace)

    var alpha: CGFloat = 1.0
    context.setFillPattern(pattern!, colorComponents: &alpha)
    context.fill(rect)

    context.addArc(
        center: CGPoint(x: 5, y: 5), radius: 5.0,
        startAngle: 0, endAngle: CGFloat(2.0 * .pi),
        clockwise: false)
    }
}

Solution

  • You have a bug. Just change second line to UIColor.white.setFill() and inside drawPattern change color to black: context.setFillColor(UIColor.black.cgColor).

    It works. I set this view on Storyboard, but if you add it from code try this:

    let dottedView = DottedBackgroundView()
    dottedView.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(dottedView)
    
    NSLayoutConstraint.activate([
        dottedView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
        dottedView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
        dottedView.topAnchor.constraint(equalTo: self.view.topAnchor),
        dottedView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
    ])
    

    You need to set constraints, because your custom view doesn't have defined size, therefore it's not able to resize properly.