在等待 Alamofire 请求完成时使用弹出动画为 UIView 设置动画

Animate UIView using pop animation while waiting Alamofire request finishes

我正在尝试使用 Facebook 的 POP 框架为自定义按钮制作动画。在使用 Alamofire 完成请求之前,动画不会发生。

我想做的是发出请求并在等待过程中为按钮设置动画。

下面的代码在视觉上有效,但它在动画完成后执行请求。

 func animate(tappedView:UIView){

    let rotation = POPBasicAnimation(propertyNamed: kPOPLayerRotationX)
    rotation.duration = 2.0
    rotation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    tappedView.layer.anchorPoint = CGPointMake(0.5, 0.5)
    rotation.toValue = 3*M_PI


    let scaleUp = POPBasicAnimation(propertyNamed: kPOPLayerSize)
    scaleUp.duration = 0.5
    scaleUp.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
    tappedView.layer.anchorPoint = CGPointMake(0.5, 0.5)
    let size = CGSizeMake(tappedView.frame.size.width ,tappedView.frame.size.height)
    let scaledSize = CGSizeMake(size.width * 1.5, size.height * 1.5)
    scaleUp.toValue = NSValue(CGSize: scaledSize)


    let scaleDown = POPSpringAnimation(propertyNamed: kPOPLayerSize)
    scaleDown.beginTime  = CACurrentMediaTime() + 0.5
    scaleDown.toValue = NSValue(CGSize: size)
    scaleDown.springSpeed = 4
    scaleDown.springBounciness = 8

    scaleDown.completionBlock = { (anim:POPAnimation!, finished:Bool) -> Void in

        let requestURL = self.prepare4SQrequest(withLocation: self.currentLocation)
        let request = Alamofire.request(.GET, requestURL)
        request.responseJSON{ response in
         HANDLE REQUEST RESPONSE LOGIC
    }


    tappedView.layer.pop_addAnimation(rotation, forKey: "popRotationX")
    tappedView.layer.pop_addAnimation(scaleUp, forKey: "popScaleUp")
    tappedView.layer.pop_addAnimation(scaleDown, forKey: "popScaleD")

}

我尝试使用 Alamofire 的 request.progress 但它没有用。 在此版本中,动画在请求逻辑完成时开始。

func animate(tappedView:UIView){

    let rotation = POPBasicAnimation(propertyNamed: kPOPLayerRotationX)
    rotation.duration = 2.0
    rotation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    tappedView.layer.anchorPoint = CGPointMake(0.5, 0.5)
    rotation.toValue = 3*M_PI


    let scaleUp = POPBasicAnimation(propertyNamed: kPOPLayerSize)
    scaleUp.duration = 0.5
    scaleUp.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
    tappedView.layer.anchorPoint = CGPointMake(0.5, 0.5)
    let size = CGSizeMake(tappedView.frame.size.width ,tappedView.frame.size.height)
    let scaledSize = CGSizeMake(size.width * 1.5, size.height * 1.5)
    scaleUp.toValue = NSValue(CGSize: scaledSize)


    let scaleDown = POPSpringAnimation(propertyNamed: kPOPLayerSize)
    scaleDown.beginTime  = CACurrentMediaTime() + 0.5
    scaleDown.toValue = NSValue(CGSize: size)
    scaleDown.springSpeed = 4
    scaleDown.springBounciness = 8


    tappedView.layer.pop_addAnimation(rotation, forKey: "popRotationX")
    tappedView.layer.pop_addAnimation(scaleUp, forKey: "popScaleUp")
    tappedView.layer.pop_addAnimation(scaleDown, forKey: "popScaleD")

}


func buttonTapped(gesture:UIGestureRecognizer){

    let tappedView:UIView = gesture.view!
    switch (tappedView.tag)
    {
    case 1:

        let requestURL = prepare4SQrequest(withLocation: currentLocation)
        let request = Alamofire.request(.GET, requestURL)
        request.progress({bytesRead, totalBytesRead, totalBytesExpectedToRead in
            dispatch_async(dispatch_get_main_queue()) {
                print("Total bytes to read : \(totalBytesExpectedToRead)")
                print("Total bytes read \(totalBytesRead)")
                print("Bytes read \(bytesRead)")
                self.animate(tappedView)
            }
        } )
        request.responseJSON{ response in

          HANDLE REQUEST RESPONSE LOGIC

        }

        break
      }

如有任何帮助,我们将不胜感激。

谢谢

您的 buttonTapped 函数应该如下所示

func buttonTapped(gesture:UIGestureRecognizer) {
  // 1 do your setup and switch case
  // 2 first ask alamofire to send request
  Alamofire.request(.GET, requestURL).
  responseJSON {
    response in
    // handle response here
    stopAnimation()
  }
  // 3 call your animation
  animate(tappedView)
}

现在,如果您在 animate(tappedView) 和处理 json 响应的代码上放置一个断点,您将看到您的调试器将首先在 animate 处停止,然后在一段时间后在响应代码处停止。 Alamofire 内置了多线程逻辑,所以你要求它从网络中获取一些东西,然后它会在它准备好时执行你在闭包中传递给 .response 的代码。

希望对您有所帮助!