在解雇视图后,动画完成块变得混乱

时间:2017-12-05 06:21:23

标签: ios swift uiview uinavigationcontroller

我有一个详细的viewcontroller,它包含一个带有动画图像视图的重复轮播,如下所示:

func animateCarousel1(){
    UIView.animate(withDuration: 1, delay: 3, options: .curveEaseInOut, animations: 
        //image animation
    },completion: { (_) -> Void in
        print("animation 1 complete")
        self.animateCarousel2() 
                  })
    }
func animateCarousel2(){
    UIView.animate(withDuration: 1, delay: 3, options: .curveEaseInOut, animations: 
        //image animation
    },completion: { (_) -> Void in
        print("animation 2 complete")
        self.animateCarousel1() 
                  })
    }

在弹出这个视图并返回到父视图后,我看到在调试控制台中,这些函数继续在后台被重复,同时,无限地调用。

模拟器中的CPU使用率也会跃升至90%。

在弹出viewcontroller之前,我需要做一些deinit吗?我似乎无法绕过这一个。

3 个答案:

答案 0 :(得分:1)

问题是即使动画结束也会调用完成块。所以有一些可能的解决方案:

  1. 检查完成处理程序的finished参数:

    func animateCarousel1() {
        UIView.animate(withDuration: 1, delay: 3, options: .curveEaseInOut, animations: {
            //image animation
        }, completion: { finished in
            print("animation 1 complete")
            if finished { self.animateCarousel2() }
        })
    }
    
    func animateCarousel2() {
        UIView.animate(withDuration: 1, delay: 3, options: .curveEaseInOut, animations: {
            //image animation
        }, completion: { finished in
            print("animation 2 complete")
            if finished { self.animateCarousel1() }
        })
    }
    
  2. 使用不同的动画技术,不需要这些动画例程之间的循环引用,例如:

    func animateCarousel() {
        UIView.animateKeyframes(withDuration: 8, delay: 3, options: .repeat, animations: {
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.125) {
                // animation 1
            }
            UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.125) {
                // animation 2
            }
        }, completion: nil)
    }
    

答案 1 :(得分:1)

这有可能解决您可以看到此帖link here

的问题

在deinit()控制器方法或viewDidDissapear()上使用,请尝试以下代码

deinit {
    print("deinit \(NSStringFromClass(self.classForCoder).components(separatedBy: ".").last ?? "")") // print viewcontroller deallocated
    self.view_for_remove_animations.layer.removeAllAnimations() // Forze delete animations
}

OR

 override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    print("viewDidDisappear \(NSStringFromClass(self.classForCoder).components(separatedBy: ".").last ?? "")") // print viewcontroller deallocated
    self.view_for_remove_animations.layer.removeAllAnimations() // Forze delete animations
}

试一试,并发送反馈

答案 2 :(得分:1)

原因是在动画块中,你正在使用self的强引用,这就是为什么当你弹出这个viewcontroller时它的引用计数仍然不是0,因为ARC无法释放该视图控制器的引用。

[weak self]的概念。您可以像下面那样修改代码,然后在弹出后,您将无法在调试控制台中看到这些方法调用。原因:弱自我不会增加引用计数,ARC将能够删除对象的引用

func startAnimation() {
    UIView.animate(withDuration: 0.4, animations: {[weak self] in
        self?.animateView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        print("startAnimation")
    }, completion: {[weak self]
        finished in
        self?.startAnimation2()
    })
}
func startAnimation2() {
    UIView.animate(withDuration: 0.4, animations: {[weak self] in
        self?.animateView.frame = CGRect(x: 100, y: 0, width: 100, height: 100)
        print("startAnimation2")
    }, completion: {[weak self]
        finished in
        self?.startAnimation()
    })
}