2013-04-24 3 views
0

Я SuperView под названием self.myMainViewКак анимировать виды, изменяя иерархию представлений с помощью автозапуска?

В этой точке зрения у меня есть три подвидов: UIView * view1 (зеленый вид), UIView * view2 (серый вид), UIImageView * view3

Я хочу анимацию перемещения view 3

и когда вид 3 завершен этой анимацией, чем я хочу изменить иерархию представлений, как на примерах скриншотов.

Вот пример изображения:

before:

and after our manipulations it must be

+0

какой вид вид3? – matt

+0

@matt это изображение, например, как это может быть ценным? Вид 3 может вести себя неправильно? –

+0

, чтобы я мог попытаться воспроизвести проблему. Работая над ним ... – matt

ответ

0

Проблема заключалась в ограничениях вида 3, которые не меняются после анимации, и когда мы хотим манипулировать иерархией представлений, анимация перестает работать должным образом. Мэтт сказал об этом в своем ответе, также он предлагает решение из своей великой книги: http://www.apeth.com/iOSBook/ch17.html#_animation_and_autolayout благодарю вас за это Matt.

Я немного изменил это решение и решил разместить его здесь для всех, кто в этом нуждается. Но если вы хотите понять это лучше, я настоятельно рекомендую вам прочитать главу об анимации из книги, ссылка выше.

Во-первых, нам необходимо анимировать наше движение 3, а затем изменить наши ограничения и только после этого изменить иерархию представлений.В книге нашли несколько способов сделать это, но это один казался мне лучшим:

layout = -35.0; // new constraint constant of self.view3 

NSArray *constraintsForAnimation = self.myMainView.constraints; // all constraints of superview 

NSUInteger indexOfconstraintsAttribute = [constraintsForAnimation 
indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ // get index of constraint of view 3 

    NSLayoutConstraint *constraint = obj; 


    return (([constraint.firstItem isEqual: self.view3])) ? idx : NO; // return this index if we found constraint of view 3 

}]; 


constraint.constant = layout; // changing the constraint of view3 

[UIView animateWithDuration:0.3 animations:^{ // animation 
    [self.view3 layoutIfNeeded]; // apply new constraints to view3 
}]; 


[self.myMainView exchangeSubviewAtIndex:3 withSubviewAtIndex:4];// toggle view 1 with view 2 

Мы перемещаем наш взгляд 3 только с помощью ограничений, мы не ставим рамку или центр вида собственности. Хорошо, мы сделали это, и это работает так, как я хочу. Надеюсь, это тоже поможет.

1

Что вы делаете, это нормальный, стандартный способ изменить порядок послойного взглядов. Поэтому проблема не в этом, а в ваших словах «Но это нарушает мою анимацию» и «сокрушает мою анимацию». Таким образом, проблема связана с вашей анимацией, если ее можно «нарушить» и «раздавить», переставив слои. Однако вы не предоставляете в своем вопросе никакой информации об анимации! Но это, безусловно, является сердцем проблемы.

EDIT: Теперь, когда вы разместили код анимации, я смог проверить, и я вижу, в чем проблема. Проблема в том, что вы используете автозапуск.

view3 позиционируется ограничениями. Когда вы анимируете позицию view3, вы нарушаете эти ограничения, но это не сразу становится очевидным. Но когда вы меняете порядок наложения view1 и view2, выполняется макет! Затем принудительно применяются ограничения на view3. Поскольку эти ограничения не изменились, мы видим view3 назад, где вы его первоначально имели.

Самое простое решение - отключить автозапуск, если он вам не нужен. В противном случае вам придется изменить ограничения, после анимации или как часть анимации. Фактически, вы можете переместить view3, оживив свои позиционные ограничения. Я опишу все это в своей книге: http://www.apeth.com/iOSBook/ch17.html#_animation_and_autolayout

+0

спасибо!) Вчера я прочитал главу из вашей книги о взглядах :) спасибо за вашу работу, которую вы делаете отлично! –

+0

Надеюсь, этот раздел книги вам поможет. Он начинается с примера, очень похожего на ваше, где вид «отскакивает» туда, где он начинался. Затем я предлагаю различные решения проблемы. – matt

+0

привет матовый, я хочу спросить вас об одной проблеме, которая находится в вашем коде из вашей книги, я использовал код, который олицетворяет изменение ограничения, которое позиционирует представление, и вот код, который имеет эту проблему и выбрасывает исключение: 'Завершение приложения из-за неотображенного исключения 'NSRangeException', причина: '*** - [__ NSArrayM objectAtIndex:]: индекс 128552240 за пределами границ [0 .. 17]' 'код:' NSUInteger indexOfconstraintsAttribute = [constraintsForAnimation indexesOfObjectsPassingTest:^BOOL (id obj, NSUInteger idx, BOOL * stop) {...} 'xcode беспокоится о типе NSUInteger, это должно быть NSIndexSet, почему? –

0

Если все, что вы хотите сделать, это переключить, какое из двух подзонов находится друг над другом, вы можете просто использовать [UIView bringSubviewToFront:], а не просто возиться с порядком вашего подсмотра массив? Это может решить проблемы с анимацией. Другая вещь, которую я бы попробовал, - поставить if(finished) вокруг вашего звонка на exchangeSubviewAtIndex, чтобы убедиться, что он не мешает другим анимированным представлениям.

+0

'bringSubviewToFront' не подходит для моих целей, я уже пробовал, но я попробую' if (finished) 'прямо сейчас –

+0

nope, это не работает –

+0

hm okay Я буду ткнуть и посмотреть, могу ли я найти решение. – cowfaboo

Смежные вопросы