Анимированные анимации UIImage не работают в режиме просмотра без анимации
У меня есть контроллер представления, чей вид содержит 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");
Этот также работает отлично, поскольку новые переходы View на место с использованием указанной пользовательской анимации.
Но когда я нажимаю AnimationViewController
на стек с помощью анимированного перехода, он отображает, но анимация не запускается. Вместо этого он показывает первый кадр анимации (первое изображение в списке) и не запускает его.
Итак, что-то о переходе нарушает способность анимировать a UIImage
в новом контроллере представления, но я просто не могу понять, что с этим делать.
Обновить. Я заметил, что если я коснусь кнопки назад навигационной кнопки ControlController, но затем откройте кнопку "Назад" и отпустите (так что я вообще не вернусь), начинается анимация играть!
Ответы
Ответ 1
Ну, я никогда не понял, в чем проблема, но оказалось, что в UIImage
произошла какая-то утечка памяти, так что на некоторых телефонах мой код рушился.
Итак, я переписал его, чтобы сделать анимацию вручную. Теперь я устанавливаю таймер и сохраняю переменную индекса кадра, и каждый раз, когда таймер звонит, я сам меняю изображение. Это равносильно тому, что и устраняет эту проблему.
Ответ 2
PushViewController работает следующим образом: над текущим контроллером представлений размещается следующий контроллер представления, который вы можете сказать, нажав на стек. Из документов Apple ясно, что вам нужно нажимать контроллеры просмотра либо с анимацией, либо без нее.
Работать вокруг:
- Установите рамку следующего вида представления контроллера вида x за пределы
экран справа
- Предположим, что ширина экрана равна 320, затем установите положение x следующего
вид 320.
- Добавьте следующий вид в качестве подзаголовка к существующему.
- Теперь сделайте свою собственную анимацию.
Другая работа вокруг: (немного больше накладных расходов)
- Сделать снимок программным способом текущего вида.
- Добавить образ моментального снимка в качестве начального представления следующего контроллера представления.
- Теперь нажмите контроллер просмотра без анимации. (Пользователь все равно увидит старое представление)
- В viewDidAppear нового контроллера просмотра запустите свою пользовательскую анимацию.
[Я должен предупредить вас, что этот метод снятия снимка может дать вам небольшую задержку в более старых устройствах. Новые устройства довольно быстр, вы не увидите никаких лаг]
Сообщите мне, если возникнут какие-либо проблемы, если вы выполняете какие-либо из этих решений.
Ответ 3
Попробуйте добавить анимационный бит в ViewDidAppear, а не ViewDidLoad. Кроме того, попробуйте использовать контрольные точки и NSLogs, чтобы следить за тем, что происходит после анимации, начиная с ViewDidLoad и ViewDidAppear. Попробуйте повторить анимацию навсегда, чтобы вы могли видеть, была ли она когда-либо анимацией или нет.
Ответ 4
Мне очень любопытно, что здесь виновник. Почему анимация не отображается правильно в некоторых случаях?
Моя теория заключается в том, что вы разместили анимационный код в viewWillAppear, а не viewDidAppear. Анимационный код не работает должным образом при размещении в методах WILL или SHOULD.
Можете ли вы отправить сообщение о том, что вызвало проблему?
Ответ 5
Подозрение # 1
Я уверен, что ваш код не вызывается, потому что он находится в ViewDidLoad. Я считаю, что вы создаете персонализированный стек представлений, это означает, что вам нужно использовать методы ChildViewController из Cocoa.
Я не знаком с MonoTouch (я пишу только CocoaTouch), поэтому это может быть не на 100% правильно
Я бы утешил методы viewDidLoad и viewDidAppear и абсолютно убедился, что они вызываются. Я подозреваю, что viewDidLoad НЕ. И это вызывает появление viewDidLoad в UIImageView.
В вашем коде вам, вероятно, понадобится эквивалент (от objective-c):
[self addChildViewController:viewController];
// OR?
[base addChildViewController:viewController];
Это указывает родительскому viewController, что Child был сделан видимым, поэтому при необходимости вызовите методы viewDidLoad/Appear и Unload/Disappear. Это может не существовать в MonoTouch, иначе методы Push могут быть не полностью реализованы, поэтому вам может понадобиться сделать некоторые хакерские (bad) вещи, например, вручную вызвать метод viewDidLoad вручную.
Подозрение № 2
Также может быть, что ваша переменная "список" (та, которая держит изображения) равна нулю. Если это произойдет, анимация не будет работать. ИЛИ, может быть, это связано с продолжительностью вашей анимации, постарайтесь установить ее во что бы то ни стало, чтобы она повторялась навсегда. Убедитесь, что он не запускает REAL FAST каким-то образом, и вам просто не хватает его.
начать философское размышление
Либо это, либо начните изучение фактического развития Cocoa:) Не подразумевается как пламя, но определенно означает серьезно, у вас возникнут проблемы с попыткой разработки приложений через слои перевода (пользовательские языковые мосты, предназначенные для написания базового языка платформы/приложения/платформы).
Titanium/MonoTouch/PhoneGap никогда не будет работать в качестве надежных или высококачественных приложений как реальных Objective-C. И кроме того, как только вы узнаете Cocoa, это изменит, как вы напишете все остальное, и я сомневаюсь, что вы захотите вернуться. Как замечательный сайт с таким же названием говорит: "Cocoa - моя девушка"
Ответ 6
Позвольте мне рассказать что-то о пользовательском интерфейсе в IOS. В IOS доступ к элементам пользовательского интерфейса ограничен одним потоком.
Единственный поток всегда будет mainThread, за исключением случая, когда вы запускаете анимацию.
Следовательно, когда u выполняет число анимации в том же экземпляре, вы должны использовать
-
beginAnimation.
-
setFrame (или) некоторые методы, которые изменяют состояние элемента пользовательского интерфейса.
-
Повторите шаг2 для всех этих объектов u, планирующих анимацию.
-
comitAnimations для выполнения всех анимаций одновременно. (с помощью comit-анимации убедитесь, что все анимации выполняются в одном потоке)
Итак, я думаю, вот что происходит в случае ура.
-
Viewcontroller запустил анимацию, чтобы вставить контроллер представления в стек.
-
Представление изображения начало новую анимацию перед завершением первой анимации.
Посмотрите на ссылки, чтобы получить четкое представление link1 и link2.
Хорошо. Перейдем к решению
Добавить ivar и сохраненное свойство ctlAnimations в ваш класс
В 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 секунды, чтобы она выполнялась после первой анимации и затем начала анимацию изображения.
Идите вперед и попробуйте
Ответ 7
Существует концепция для основного потока. Таким образом, UIAnimation на самом деле работает в основном потоке, и в то же время может случиться так, что другая задача выполняется в одной и той же главной теме. Таким образом, такой случай, как IOS, будет давать предпочтение в соответствии с идентификатором процессов каждого процесса за раз и для решения вам нужно сделать фоновый поток для тех же операций.