Вопрос

у меня есть UIView с кучей подписаний, все расположены с использованием layoutSubviews. Анкет Когда view Изменен, относительные позиции все изменяются. Я бы хотел, чтобы эти повторные рассчинения произошли во время анимированного изменения размера (используя +[UIView beginAnimations:] вызовы). Это, похоже, не происходит. Любые идеи?

Это было полезно?

Решение

Предположение: вы хотите иметь несколько шагов анимации (т.е. позиция не меняется линейно с размером кадра).

Это невозможно при единой «стандартной» анимации Uiview. Почему? Кадр/границы устанавливаются только один раз.

Основная анимация Имеет три «слои -деревья»:

  • А Модельное дерево Это где ваше приложение думает, что все есть.
  • А Дерево презентации Примерно то, что отображается на экране.
  • А рендеринг дерево Примерно то, какая основная анимация является композицией.

Uiview - это (несколько тонкая) обертка вокруг слоя модели. Во время анимации Uiview основная анимация обновляет дерево презентации/рендеринга - дерево модели представляет конечную точку анимации. В результате ваш код может (по большей части) рассматривать анимации как мгновенное, перемещая вид от A к B мгновенно перемещает его в B; Изменение просто анимировано с пользователем.

Есть более сложные вещи, которые вы можете сделать с Calayer/Caanimation напрямую, но я не исследовал так много.

Вы можете объединить несколько анимаций вместе, используя -[uiview setanimationdidstopselector:]. (Вы также можете попробовать использовать несколько анимаций вместе с SetanimationDelay:, но я не уверен, что происходит с несколькими анимациями на одном и том же свойстве; вам может повезло с SetanimationBeginsfromCurrentState :.)

Если вам нужен действительно мелкозернистый контроль, CadisPlayLink (OS 3.1+)-это таймер, который стреляет после каждого экрана обновления. Опция завышенного (для поддержки 3.0) - использовать NSTIMER при 30/60 Гц или около того.

Другие советы

Завершив @Gizzlynetch's Anwer, вы можете установить UIViewAnimationOptionLayoutSubviews опция анимации, поэтому вам не нужно звонить layoutIfNeeded:

-(void)someMethod{
    double duration = ...;
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        self.frame = ...;
    } completion:nil];
}

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

-(void)layoutSubviews{
     [super layoutSubviews];
     // layout your subviews here, or whatever
}

-(void)someMethod{
    double duration=...;
    [UIView animateWithDuration:duration animations:^{
        self.frame = ...;
        [self layoutIfNeeded];
    }];
}

Конечно, вы можете назвать этот метод из другого объекта. «Трюк» состоит в том, чтобы вызовать Layoutifneeded (или LayoutoutSupwies напрямую - то же самое, если вы измените кадр, называется SetNeedSlayout).

Как TC. Хорошо объяснил «слойные деревья», вы просто заставляете слой презентации отобразить последний этап уровня модели с анимацией.

Преимущество этого метода заключается в возможности управления, когда изменение кадра/границы анимировано и когда оно мгновенно.

Надеюсь, это кому -то поможет :).

Публикация для полноты. Спасибо TC. Для объяснения того, что я хочу сделать, точно не поддерживается основной анимацией.

В конце концов я придумал разумное решение. Вместо того, потом макет мои подвесития в -layoutsubviews, я делаю это в -седбендс:. Затем, когда я обертываю hetbounds: звоните в Uiview +BeginAnimations: Block, эти вызовы позиционирования также анимированы, и конечный результат -все, что правильно оживляет, где он должен Бог.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top