当其他函数中的循环完成 运行 时,如何调用 swift 中的函数?
how can I call a function in swift when the loop in other function completes running?
我目前正在 Swift
中编写一个函数来从地图中删除所有注释。
我想在删除它们时添加淡出效果,所以我想到了以下论点:
迭代所有注释
对于每个注释,使用动画将其 alpha 更改为 0
当一切都完成后 - 从地图上删除注释。
到目前为止,我的代码已经更改了每个标记的 alpha,但我不知道如何在其他所有操作完成后调用负责删除标记的函数。
我有两个功能:
func removeMarkersFromMap(){
self.array.removeAll()
let annotationsToRemove = mapView.annotations.filter { [=12=] !== mapView.userLocation }
for annotation in annotationsToRemove {
let pinView = mapView.view(for: annotation)
UIView.animate(withDuration: 2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
pinView?.alpha = 0.0
}, completion: { (finished: Bool) -> Void in
print("removed single pin")
})
}
}
和:
func removeCompletelyAnnotations(){
let annotationsToRemove = mapView.annotations.filter { [=13=] !== mapView.userLocation }
self.mapView.removeAnnotations( annotationsToRemove )
}
当第一个函数内的循环完成后,如何调用第二个函数?
我对这种事情使用的技巧是将最终完成代码放在对象实例的 deInit 方法中,该实例由各个完成中的 捕获。
例如:
class FinalCompletion
{
var codeBlock:()->()
init(_ code:@escaping ()->()) { codeBlock = code }
func waitForLast() {}
deinit { codeBlock() }
}
因此在您的调用代码中,您可以按如下方式进行:
func removeMarkersFromMap()
{
...
// setup the final completion in a local variable
let removeAnnotation = FinalCompletion(removeCompletelyAnnotations)
for annotation in annotationsToRemove
{
let pinView = mapView.view(for: annotation)
UIView.animate(withDuration: 2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
pinView?.alpha = 0.0
}, completion: { (finished: Bool) -> Void in
print("removed single pin")
// reference the local variable to make it part of the capture
removeAnnotation.waitForLast()
})
}
}
它的工作方式是局部变量(FinalCompletion 对象)将保持 "alive" 只要至少一个完成块还处于活动状态。执行完成块时,它们会超出范围并释放对捕获的局部变量的控制。当最后一个完成块被执行并超出范围时,局部变量不再有任何对它的引用,因此它也超出范围。这是它的 deinit 方法被调用的时候。 (即在执行完所有完成块之后)。
为什么不简单地删除完成块中的注释而不是使用单独的方法
for annotation in annotationsToRemove {
let pinView = mapView.view(for: annotation)
UIView.animate(withDuration: 2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
pinView?.alpha = 0.0
}, completion: { (finished: Bool) -> Void in
self.mapView.removeAnnotation(annotation)
})
}
}
我目前正在 Swift
中编写一个函数来从地图中删除所有注释。
我想在删除它们时添加淡出效果,所以我想到了以下论点:
迭代所有注释
对于每个注释,使用动画将其 alpha 更改为 0
当一切都完成后 - 从地图上删除注释。
到目前为止,我的代码已经更改了每个标记的 alpha,但我不知道如何在其他所有操作完成后调用负责删除标记的函数。
我有两个功能:
func removeMarkersFromMap(){
self.array.removeAll()
let annotationsToRemove = mapView.annotations.filter { [=12=] !== mapView.userLocation }
for annotation in annotationsToRemove {
let pinView = mapView.view(for: annotation)
UIView.animate(withDuration: 2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
pinView?.alpha = 0.0
}, completion: { (finished: Bool) -> Void in
print("removed single pin")
})
}
}
和:
func removeCompletelyAnnotations(){
let annotationsToRemove = mapView.annotations.filter { [=13=] !== mapView.userLocation }
self.mapView.removeAnnotations( annotationsToRemove )
}
当第一个函数内的循环完成后,如何调用第二个函数?
我对这种事情使用的技巧是将最终完成代码放在对象实例的 deInit 方法中,该实例由各个完成中的 捕获。
例如:
class FinalCompletion
{
var codeBlock:()->()
init(_ code:@escaping ()->()) { codeBlock = code }
func waitForLast() {}
deinit { codeBlock() }
}
因此在您的调用代码中,您可以按如下方式进行:
func removeMarkersFromMap()
{
...
// setup the final completion in a local variable
let removeAnnotation = FinalCompletion(removeCompletelyAnnotations)
for annotation in annotationsToRemove
{
let pinView = mapView.view(for: annotation)
UIView.animate(withDuration: 2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
pinView?.alpha = 0.0
}, completion: { (finished: Bool) -> Void in
print("removed single pin")
// reference the local variable to make it part of the capture
removeAnnotation.waitForLast()
})
}
}
它的工作方式是局部变量(FinalCompletion 对象)将保持 "alive" 只要至少一个完成块还处于活动状态。执行完成块时,它们会超出范围并释放对捕获的局部变量的控制。当最后一个完成块被执行并超出范围时,局部变量不再有任何对它的引用,因此它也超出范围。这是它的 deinit 方法被调用的时候。 (即在执行完所有完成块之后)。
为什么不简单地删除完成块中的注释而不是使用单独的方法
for annotation in annotationsToRemove {
let pinView = mapView.view(for: annotation)
UIView.animate(withDuration: 2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
pinView?.alpha = 0.0
}, completion: { (finished: Bool) -> Void in
self.mapView.removeAnnotation(annotation)
})
}
}