ОК, думаю, я нашел проблему и возможное решение.
Ключ к пониманию проблемы - понимание того, что при вызове
[UIView animateWithDuration...]
все свойства, которые вы изменяетевнутри блока анимации немедленно изменяются .Они не меняются по мере выполнения анимации (визуально).
Так что в моем случае я анимирую contentOffset к своему целевому значению.Эта операция немедленно вызывает layoutSubviews.
В моей реализации layoutSubviews я проверяю, было ли накоплено достаточно движений.Если это так - я переставляю свои ImageViews и устанавливаю для contentOffset начальное значение .Как только я это сделаю, больше ничего не нужно анимировать, потому что ничего не изменилось!
- Animate contentOffset to X:
- вызывает setContentOffset для X:
- вызывает layoutSubview
- Устанавливает contentOffset обратно в Y!(после перестановки видов)
- Ничего не оживлять на этом этапе ...
Возможное исправление
Я не уверен, что это правильный способ, но он работает.Поэтому нам нужно убедиться, что в layoutSubviews не будет внесено никаких изменений, пока мы находимся в середине анимационного блока.
Поэтому я создал переменную экземпляра BOOL с именем isAnimating и соответствующим образом установил ее в анимации.блок:
self.isAnimating = YES;
[UIView animateWithDuration:self.transitionDuration
delay:0
options:(UIViewAnimationOptionCurveEaseOut)
animations:^{
self.contentOffset = newOffset;
}
completion:^(BOOL finished) {
self.isAnimating = NO;
[self setNeedsLayout];
}];
Теперь в макете Subviews нам нужно учесть isAnimating:
-(void) layoutSubviews
{
[super layoutSubviews];
if (self.isAnimating == NO)
{
[self rearrangeIfNecessary];
}
}
И снова работает!