iosswiftuikitcgrect

Merge overlapping CGRects


If I have a class Button:

class Button: Hashable {
    private let id: String
    var name: String
    var rect: CGRect    
}

I also have an array of Button: var buttons: [Button], how would I merge every overlapping button in the buttons array? CGRect has an intersects() -> Bool and union() -> CGRect functions.

I tried this and was getting index out of range errors:

for i in 0..<buttons.count {
        for j in (i+1)..<buttons.count {
            if buttons[i].rect.intersects(buttons[j].rect) {
                let secondRect = buttons[j].rect
                let union = buttons[i].rect.union(secondRect)
                buttons[i].rect = union
                buttons.remove(at: j)
            }
        }
    }

Solution

  • Swift for loop is static, which means that range of the index determined at the start. While buttons.count keeps decreasing when you remove a next item, both i and j are counting til the start buttons.count, that's why you get a crash.

    There's no dynamic for in swift (c-like), that's why you have to use while instead:

    var i = 0
    while i < buttons.count {
        var j = i + 1
        while j < buttons.count {
            if buttons[i].rect.intersects(buttons[j].rect) {
                let secondRect = buttons[j].rect
                let union = buttons[i].rect.union(secondRect)
                buttons[i].rect = union
                buttons.remove(at: j)
            } else {
                j += 1
            }
        }
        i += 1
    }