Steven Schveighoffer Steven Schveighoffer - 1 year ago 47
Swift Question

Equivalent for loop complex condition

I have code currently in my iOS project that looks like this:

for var i = 0; CGFloat(i) * gridSpacing.width * scale < bounds.width; ++i

I am now receiving warnings that this style for loop will be deprecated. Everywhere I look on Stack Overflow and elsewhere suggests using stride for complex for loops. However, stride doesn't help me here, as the end condition is not a simple comparison to another integer.

How do I do this in swift with a for-in loop?

Note, I could loop a CGFloat, but I want to avoid the incremental error by repeatedly adding floats.

I could also use a while loop, but I have several of these loops in the same function, and for creates a nice new scope for i. Swift doesn't seem to like arbitrary new scopes.

Answer Source

Let's go in steps:

let itemWidth = gridSpacing.width * scale
for var i = 0; CGFloat(i) < bounds.width / itemWidth; ++i {

Now you can directly

let itemWidth = gridSpacing.width * scale
let numItems = Int(floor(Double(bounds.width / itemWidth)))

for var i = 0; i < numItems; i++ {


for i in 0..<numItems {

Another option is to use while loop:

(I have used the solution you want to avoid but I feel it's still better and it's unlikely the error will be more important than the error introduced by scale).

let itemWidth = gridSpacing.width * scale
var x = 0
var index = 0

while (x < bounds.width) {
  // do something

  index += 1
  x += itemWidth