Как заставить представление сделать себя?

В моем приложении у меня есть несколько небольших подзонов. Когда пользователь отбирает subview, я помещаю один отдельный вид поверх вершины subped (одинакового размера), а затем анимируем это отдельное представление до полноэкранного размера.

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

Тем не менее, мне нужно, чтобы это расширенное представление было различным, в зависимости от того, какой подзаголовок был использован, поэтому мне нужно повторно создавать/повторно рисовать его каждый раз. Проблема заключается в том, что когда я делаю это в ответ на событие касания, метод view drawRect не вызывается до начала анимации, и в это время рамка представления является маленькой, а не полноэкранной, и в результате все неправильный.

В моем коде для сенсорного события я явно устанавливаю рамку представления в полноэкранном режиме и вызываю setNeedsDisplay перед началом анимации, но это не имеет никакого эффекта - drawRect просто не вызывается до начала анимации.

Есть ли способ принудительно перерисовать, чтобы изображение было нарисовано, пока его кадр является размером, который я хочу?

Ответы

Ответ 1

Как я уже говорил выше, Джо спросил что-то подобное (как более общий вопрос) here, которому Tom Swift предоставил ответ, который манипулирует текущим циклом запуска.

Его предложение состояло в том, чтобы заставить цикл цикла через одну итерацию сразу же после вызова -setNeedsDisplay с помощью следующего кода:

[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];

Есть некоторые оговорки к этому подходу, которые обсуждаются в комментариях там.

Кроме того, было указано, что

[CATransaction flush];

может также достичь того же эффекта, что и принудительное изменение вида.

Ответ 2

Правильный способ сделать это - просто разделить ваш метод.

Просто позвоните setNeedsDisplay, а затем вернитесь без анимации. Подождите, пока drawRect, который правильно настроит все, завершит перерисовку, а затем запустит в очередь другой метод, который начнет вашу нудную анимацию (через очередность операции или уведомление). Затем запустите анимацию. Это может произойти довольно быстро (с частотой кадров) и не требует дополнительных (опасных) рекурсивных циклов цикла или вызовов CATransaction (что может вызвать дополнительные настройки графического процессора).

Ответ 3

После вызова setNeedsDisplay может потребоваться время для вызова drawRect. Начните анимацию с короткой задержки (0,1f). Вы также можете вызвать метод анимации из [self performSelector: withObject: afterDelay:], чтобы добавить задержку, если это проще.

Ответ 4

Инженер Apple предоставил альтернативное рекомендованное решение. Используйте 2 UIViews, один маленький и один большой, с более крупным с альфой 0. Измените оба параметра, установите раму большой маленькой и измените масштаб анимации, а также увеличьте оба размера от малого до большого.