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