draw several rectangles inside one uiview

What you’re describing is about as basic as life gets. Simply think about the notion of a grid and the xy coordinates of one piece within the grid. Now you know where to place each subview.

Here, to show you the general idea, is a simplified version of what you’re doing. Imagine that we have no blank areas: just a solid grid of squares that are either red or gray. And let’s imagine that this grid is 12×8.

So to start with, how would we just construct a 12×8 grid of gray squares? In your code, you are doing it with actual drawing, in draw(_:); my approach uses subviews (and sublayers is also a possibility, if you think subviews is too much overhead), but the underlying principle is exactly the same:

// assume 12x8 squares
let xmax = 12, ymax = 8
let w = self.view.bounds.width / CGFloat(xmax)
for i in 0..<xmax {
    for j in 0..<ymax {
        let rect = CGRect(x: w*CGFloat(i), y: w*CGFloat(j), width: w, height: w).insetBy(dx: 2, dy: 2)
        let v = UIView(frame:rect)
        // v.backgroundColor = withRedOnes.contains([i,j]) ? .red : .gray
        v.backgroundColor = .gray
        self.view.addSubview(v)
    }
}

enter image description here

Do you see the key concept? i and j are the grid placement of a square. From that, we can easily calculate the rect where that square goes. That’s all there is to it!

Now specifying that something different, like a red view, goes at any particular coordinate, is trivial:

func makeGrid(withRedOnes: [[Int]]) {
    // assume 12x8 squares
    let xmax = 12, ymax = 8
    let w = self.view.bounds.width / CGFloat(xmax)
    for i in 0..<xmax {
        for j in 0..<ymax {
            let rect = CGRect(x: w*CGFloat(i), y: w*CGFloat(j), width: w, height: w).insetBy(dx: 2, dy: 2)
            let v = UIView(frame:rect)
            v.backgroundColor = withRedOnes.contains([i,j]) ? .red : .gray
            self.view.addSubview(v)
        }
    }
}

If we call that method like this:

self.makeGrid(withRedOnes:[[6,3], [7,3]])

Then we get this:

enter image description here

Okay, now. In real life, you’re not doing to use a mere UIView as each square. You will have your own UIView subclass that knows how to draw itself: with a color, with a number, whataever. And you won’t reconstruct all the views every time something changes; you will just change that one view within the grid, removing it or placing it, changing the way it draws itself, whatever.

As practice, I suggest you try writing a simpler grid-based app, such as a tic-tac-toe game (3×3 grid of “O” and “X”). Once you have that down, you will just tweak it successively to do all sorts of fancy things, like offsetting or centering a row of the grid and other requirements you may have in order to “draw” a theatre layout.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top