我有一个视图控制器,其视图包含执行动画的UIImageView
:
//AnimationViewController::ViewDidLoad event:
var ctlAnimations = new UIImageView();
ctlAnimations.AnimationImages = list.ToArray(); //<--list contains the UIImages
ctlAnimations.AnimationDuration = 1.0 * list.Count;
ctlAnimations.StartAnimating();
this.Add(ctlAnimations);
这非常有效:当我将AnimationViewController
推到导航堆栈上时,它会显示并动画UIImage
。
但现在我需要使用自定义动画转换显示AnimationViewController
:
var transition = CATransition.CreateAnimation ();
transition.Duration = 0.3f;
transition.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
transition.Type = CATransition.TransitionFade;
this.View.Layer.AddAnimation (transition, "fade");
//viewController is being pushed with animated=false, because we have a custom animation
base.PushViewController (viewController, false);
this.View.Layer.RemoveAnimation("fade");
此也完美无缺,因为新视图使用指定的自定义动画转换到位。
但是当我使用动画过渡将AnimationViewController
推入堆栈时,会显示但动画无法运行。相反,它显示动画的第一帧(列表中的第一个图像),并且不运行它。
因此,关于转换的一些事情正在破坏在新视图控制器中设置UIImage
动画的能力,但我根本无法弄清楚如何处理它。
更新:我注意到如果我点击NavigationController的后退按钮,然后离开后退按钮放开(所以我实际上不回去),动画开始玩!
答案 0 :(得分:1)
PushViewController的工作方式如下:在当前视图控制器上放置下一个视图控制器,您可以将其推入堆栈。从Apple docs明确表示,你需要使用动画或不使用动画来推动视图控制器。
解决方法:
另一种解决方法:(虽然有点开销)
[我必须警告你,这种拍摄快照的方法可能会让你在旧设备上有一点延迟。较新的设备非常快,你不会看到任何滞后]
如果您正在实施任何这些解决方案,请告诉我。
答案 1 :(得分:0)
尝试将动画位放在ViewDidAppear而不是ViewDidLoad中。此外,尝试使用断点和NSLog来跟踪动画后发生的事情,从ViewDidLoad和ViewDidAppear开始。尝试让动画永远重复,这样你就可以看到它是否曾经动画过。
答案 2 :(得分:0)
我很好奇这里的罪魁祸首是什么。为什么动画在某些情况下无法正确显示?
我的理论是你已经在viewWillAppear而不是viewDidAppear中放置了动画代码。置于WILL或SHOULD方法中时,动画代码无法正常运行。
请您回复导致问题的原因吗?
答案 3 :(得分:0)
我打赌你的代码没有被调用,因为它在ViewDidLoad中。我相信您正在创建自定义视图堆栈,这意味着您需要使用Cocoa中的ChildViewController方法。
我不熟悉MonoTouch(我只写纯CocoaTouch),所以这可能不是100%正确
我会安慰你的viewDidLoad和viewDidAppear方法,并绝对确保它们被调用。我怀疑viewDidLoad不是。这导致在UIImageView上没有调用viewDidLoad。
在您的代码中,您可能需要等同于(来自objective-c):
[self addChildViewController:viewController];
// OR?
[base addChildViewController:viewController];
这告诉'parent'viewController Child已被显示,因此在适当时调用viewDidLoad / Appear和Unload / Disappear方法。这可能不存在于MonoTouch中,或者Push方法可能无法完全实现,因此您可能需要执行一些hacky(错误)之类的操作,例如手动调用viewDidLoad方法。
也可能是你的'list'变量(持有图像的变量)为零。如果发生这种情况,动画将无法运行。或者它可能与动画的持续时间有关,尝试将其设置为使其永远重复的任何内容。确保它没有以某种方式运行 REAL FAST 而你只是错过它。
开始哲学思考
或者开始学习实际的Cocoa开发:)不是意味着火焰,但绝对意味着严重,你会遇到试图通过翻译层开发应用程序的问题(自定义语言 - 桥梁意味着绕过写一个基本语言框架/应用/平台)。
Titanium / MonoTouch / PhoneGap永远不会像真正的Objective-C那样生成强大或高质量的应用程序。除此之外,一旦你学习了Cocoa,它将改变你写其他所有内容的方式,我怀疑你会想要回去。正如同名的精彩网站所说,“可可是我的女朋友”
答案 4 :(得分:0)
让我讲一下IOS中的UI。在IOS中,对UI元素的访问仅限于一个线程。
除了运行动画的情况外,单个线程始终是mainThread。
因此,当您在同一个实例中执行动画数量时,您必须使用
beginAnimation。
setFrame(或)一些改变UI元素状态的方法。
对您计划设置动画的所有对象重复步骤2.
comitAnimations一次执行所有动画。 (使用comit动画确保所有动画都在同一个线程上执行)
所以,我想这就是你的情况。
Viewcontroller启动了一个动画,将视图控制器推入堆栈。
图像视图在完成第一个动画之前启动了另一个动画。
好吧让我们进入解决方案
将一个名为ctlAnimations的ivar和保留属性添加到您的班级
在ViewDidLoad(或)ViewDidAppear
self.ctlAnimations = new UIImageView(); ctlAnimations.image=(UIImage*)[list.toArray() objectAtIndex:0]; this.Add(ctlAnimations); [self performSelector:@selector(startAnimatingImage) afterDelay:0.1];
使用以下代码
创建一个名为startAnimatingImage的私有方法self.ctlAnimations.AnimationImages = list.ToArray(); ctlAnimations.AnimationDuration = 1.0 * list.Count; ctlAnimations.StartAnimating();
在一个简短的介绍中,我们刚刚显示了第一张图像,然后我们将动画开始延迟1秒,以便在第一次动画后执行,然后开始为图像设置动画。
来吧试一试
答案 5 :(得分:0)
主线程有概念。所以UIAnimation实际上可以在主线程上运行,同时可能会发生另一个任务在同一主线程上执行的情况。所以像IOS这样的情况会根据每个进程的进程id一次优先对于解决方案,您需要为相同的操作创建后台线程。
答案 6 :(得分:0)
好吧,我从来没有想出这里的问题是什么,但事实证明在UIImage
中存在某种内存泄漏,以至于在某些手机上我的代码崩溃了。
所以我重写了它以手动完成动画。现在我设置一个计时器并保留一个帧索引变量,每次计时器响铃时我自己更改图像。这相当于同样的事情,事实证明它解决了这个问题。