简体   繁体   中英

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)
            }
        }
    }

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM