I'm trying to draw rectangles pattern using DrawRect like this:
Currently, I'm doing this like so:
class PatternView: UIView {
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
let numberOfBoxesPerRow = 7
let boxSide: CGFloat = rect.width / CGFloat(numberOfBoxesPerRow)
var yOrigin: CGFloat = 0
var xOrigin: CGFloat = 0
var isBlack = true
for y in 0...numberOfBoxesPerRow - 1 {
yOrigin = boxSide * CGFloat(y)
for x in 0...numberOfBoxesPerRow - 1 {
xOrigin = boxSide * CGFloat(x)
let color = isBlack ? UIColor.red : UIColor.blue
isBlack = !isBlack
context?.setFillColor(color.cgColor)
let rectnagle = CGRect(origin: .init(x: xOrigin, y: yOrigin), size: .init(width: boxSide, height: boxSide))
context?.addRect(rectnagle)
context?.fill([rectnagle])
}
}
}
}
It's working but I'm trying to optimize it.
Any help will be highly appreciated!

It's difficult to answer "abstract" questions... which this one is, without knowing if you've run some tests / profiling to determine if this code is slow.
However, a couple things you can do to speed it up...
Take a look at this modification:
There are other options... create a "pattern" background color... use
CAShapeLayers and/orCAReplicatorLayers... for example.Edit
The reason you are getting "blurry edges" is because, as you guessed, you're drawing on partial pixels.
If we modify the values to use whole numbers (using
floor()), we can avoid that. Note that the wholeNumberBoxSide * numBoxes may then NOT be exactly equal to the view's rect, so we'll also want to inset the "grid":We could also get the scale of the main screen (which will be 2x or 3x) and round the boxSide to half- or one-third points to align with the pixels... if really desired.
Edit 2
Additional modifications... settable colors and number of boxes.
Also, using this extension:
We can round the coordinates to match the screen scale.
PatternView class
Example Controller View class
Sets up two pattern views... both start at 7 boxes... each tap anywhere increments the boxes per row in the bottom view.
Here's how it looks with 21 boxes per row (actual size - so really big image):
and zoomed-in 1600%:
Note the red borders... I set the background of the view to red, so we can see that the grid must be inset to account for the non-whole-number box size.
Edit 3
Options to avoid "blurry edges" ...
Suppose we have a view width of
209and we want10boxes.That gives us a box width of 20.9 ... which results in "blurry edges" -- so we know we need to get to a whole number.
If we round it, we'll get
21--21 x 10 = 210which will exceed the width of the view. So we need to round it down (floor()).So...
Option 1:
Option 2:
Option 3: