【问题标题】:how can I call a function in swift when the loop in other function completes running?当其他函数中的循环完成运行时,如何快速调用函数?
【发布时间】:2017-03-25 14:23:45
【问题描述】:

我目前正在Swift 中编写一个函数来删除地图中的所有注释。 我想在它们被移除时添加淡出效果,所以我想到了以下论点:

  • 遍历所有注释

  • 通过动画将每个注释的 alpha 更改为 0

  • 一切完成后 - 从地图中删除注释。

到目前为止,我的代码已经更改了每个标记的 alpha,但我不知道如何在其他所有操作完成后调用负责删除标记的函数。

我有两个功能:

func removeMarkersFromMap(){
    self.array.removeAll()
    let annotationsToRemove = mapView.annotations.filter { $0 !== 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 { $0 !== mapView.userLocation }
    self.mapView.removeAnnotations( annotationsToRemove )
}

第一个函数内的循环完成后如何调用第二个函数?

【问题讨论】:

    标签: swift swift3 android-mapview mkannotation


    【解决方案1】:

    我用于这种事情的技巧是将最终完成代码放在对象实例的 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 对象)就会保持“活动状态”。当完成块被执行时,它们会超出范围并释放它们对捕获的局部变量的持有。当最后一个完成块被执行并超出范围时,局部变量不再有任何对它的引用,因此它也超出了范围。这是调用其 deinit 方法的时候。 (即在所有完成块都已执行之后)。

    【讨论】:

    • 有没有办法给removeCompletelyAnnotations添加参数?目前我正在修改我的代码和函数removeMarkersFromMap 将采用我想传递给removeCompletelyAnnotationsString 变量。我该怎么做?
    • FinalCompletion 实际上需要一个闭包,所以你可以这样写: let removeAnnotation = FinalCompletion({ self.removeCompletelyAnnotations(..your parameters) })
    【解决方案2】:

    为什么不简单地删除完成块中的注释而不是使用单独的方法

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

    【讨论】:

      猜你喜欢
      • 2020-11-29
      • 1970-01-01
      • 2018-01-14
      • 2019-03-25
      • 2017-08-07
      • 1970-01-01
      • 2014-05-12
      • 1970-01-01
      相关资源
      最近更新 更多