Анимированные анимации 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, будет давать предпочтение в соответствии с идентификатором процессов каждого процесса за раз и для решения вам нужно сделать фоновый поток для тех же операций.