Reputation: 14310
I have this code:
for var i = 0; i < self.blockViews.count; i++ {
UIView.animateWithDuration(0.2, animations: {
// Some animation
}, completion: {
completion in
// i is always blockViews.count as the for loop exits before completion closure is called
if i == 0 {
// Some completion handling
}
})
}
I am trying to use i
inside my closure; is there a way to do this other than assigning it to a let
, and then using it (pass by value)?
for var i = 0; i < self.blockViews.count; i++ {
let copyOfI = i
UIView.animateWithDuration(0.2, animations: {
// Some animation
}, completion: {
completion in
if copyOfI == 0 {
// This works
}
})
}
Upvotes: 2
Views: 270
Reputation: 72760
Actually there's a way to achieve that, and it's called the capture list: you simply have to list the variables you want to capture as a comma separated list enclosed in square brackets - in your case, it's just [i]
:
for var i = 0; i < self.blockViews.count; i++ {
UIView.animateWithDuration(0.2, animations: {
// Some animation
}, completion: {
[i] completion in
// ^^^ capture list is here
// i is always blockViews.count as the for loop exits before completion closure is called
if i == 0 {
// Some completion handling
}
println(i)
})
}
Reference: Closure Expression
Old answer
You can enclose the loop code in a closure and pass the index as a closure parameter:
for var i = 0; i < self.blockViews.count; i++ {
{ (index) in
UIView.animateWithDuration(0.2, animations: {
// Some animation
}, completion: {
completion in
// i is always blockViews.count as the for loop exits before completion closure is called
if index == 0 {
// Some completion handling
}
})
}(i)
}
Upvotes: 3
Reputation: 2269
You either have to create a copy using a let (like you have done in your question) or pass it into the closure through the closure's parameters.
Seeing as you're using a UIView.animateWithDuration closure, your best bet is assigning it to a let variable inside your closure.
Upvotes: 1