更改viewController时保持动画

时间:2017-12-09 15:27:23

标签: ios swift animation swift3 uiviewcontroller

我正在尝试在个人资料图片后面编码#include "stdafx.h" #include <iostream> #include <Windows.h> #include <Psapi.h> using namespace std; int main() { wchar_t processPath[MAX_PATH]; HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, 3820); GetProcessImageFileName(hProcess, processPath, MAX_PATH); CloseHandle(hProcess); wchar_t * pwc; pwc = wcsstr(processPath, L"\\Device\\HardiskVolume1"); wcscpy_s(pwc, 100, L"C:", 100); wcout << processPath; return 0; } ,以鼓励用户点击它。 这是一个变得越来越小的圆圈。

animation

enter image description here

问题在于,当我转到另一个override func layoutSubviews() { super.layoutSubviews() UIView.animate(withDuration: 1.0, delay: 0, options: [.repeat, .autoreverse], animations: { self.bouncedView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3) }, completion: nil) } 时,动画停止并且圆圈保持不变,就像屏幕截图一样。你知道我怎么能避免这个问题吗?

2 个答案:

答案 0 :(得分:1)

在ViewDidAppear上转换为.identity。类似下面的代码:

class HomeController: UIViewController {

@IBOutlet weak var viewToAnimate: UIView!
override func viewDidLoad() {
    super.viewDidLoad()
}

override func viewWillAppear(_ animated: Bool) {
    self.viewToAnimate.transform = .identity
    animateView()
}

func animateView(){
    UIView.animate(withDuration: 1.0, delay: 0, options: [.repeat, .autoreverse], animations: {

        self.viewToAnimate.transform = CGAffineTransform(scaleX:
            1.3, y: 1.3)

    }, completion: nil)
}

}

您可能已经猜到的问题是UIView.animate仅在ViewDidLoad方法上调用,并且由于我们在从另一个方法返回此ViewController时无法访问该代码,因此最好启动动画在ViewWillAppear方法中。

如果在选项卡之间切换时出现同样的问题,那么请为要设置动画的视图创建一个单独的UIView子类,然后按以下步骤操作:

class AnimateView: UIView {

override func awakeFromNib() {
    super.awakeFromNib()
}

override func willMove(toWindow newWindow: UIWindow?) {
    super.willMove(toWindow: newWindow)
    self.transform = .identity
    animateView()
}

func animateView(){
    UIView.animate(withDuration: 1.0, delay: 0, options: [.repeat, .autoreverse], animations: {

        self.transform = CGAffineTransform(scaleX:
            1.3, y: 1.3)

    }, completion: nil)
}

}

在这里,您已将animate函数带到UIView对象,每当视图出现时,动画都将被重置。

答案 1 :(得分:0)

好吧,我还没有一个令人满意的答案(至少那会让我满意),但我想通过一些实验来增加至少一些我能够得到的见解。

首先,当viewController当前不是呈现时,动画似乎结束了。在您的情况下,这意味着动画停止并以状态结束,其中视图大1.3倍,并停止重复。 layoutSubviews只有在您第一次出现时才会被调用。至少viewController.viewDidLayoutSubviews仅在开始时调用,而不是在您返回时调用(因此当视图重新出现时layoutSubviews将不会被执行) - 因此动画将不会重新启动。

我试图将动画移动到viewDidAppear的{​​{1}} - 这也不起作用,因为停止动画导致视图已经缩放1.3次的状态。在创建动画之前将状态重置为UIViewController确实有效。

正如我所说的,这可以为你提供如何使其工作的解决方法,但是,我认为你真正想要的是一些钩子,它会告诉你的视图(而不是viewController)它再次呈现。但是以下最小的例子至少可以帮助其他人看一看,而不是从头开始。

CGAffineTransform.identity

修改

我添加了几行来检查import UIKit import PlaygroundSupport class MyViewController : UIViewController { let animator = UIViewPropertyAnimator(duration: 1, timingParameters: UICubicTimingParameters(animationCurve: .linear)) init(title: String) { super.init(nibName: nil, bundle: nil) self.title = title } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } let animatableView = UIView() override func loadView() { let view = UIView() view.backgroundColor = .white animatableView.frame = CGRect(x: 150, y: 400, width: 100, height: 100) animatableView.backgroundColor = UIColor.magenta view.addSubview(animatableView) self.view = view } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.animatableView.transform = CGAffineTransform.identity UIView.animate(withDuration: 1.0, delay: 0, options: [.repeat, .autoreverse], animations: { self.animatableView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3) }, completion: nil) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() print("\(self.title) >> Lay out") } } let tabBar = UITabBarController() tabBar.viewControllers = [MyViewController(title: "first"), MyViewController(title: "second"), MyViewController(title: "third")] tabBar.selectedIndex = 0 // Present the view controller in the Live View window PlaygroundPage.current.liveView = tabBar 是否包含任何动画,似乎切换标签会从视图的图层中删除动画 - 因此每次视图重新出现时都必须找到添加动画的方法。 / p>

编辑2 所以我会使用@ SWAT的答案并使用self.animatableView.layer.animationKeys()代替willMove(toWindow:)