Анимация MPVolumeView на iOS 8

В iOS 8 есть проблема или фича. Когда отображается MPVolumeView, он анимируется, например, расширяется от 0 до своей ширины. Как я могу исправить такое поведение? На iOS 7 такой проблемы не было.


person Alexander Woodblock    schedule 16.09.2014    source источник
comment
Да, это определенно похоже на ошибку. Это происходит только в первый раз, когда экземпляр MPVolumeView добавляется в суперпредставление. Если вы удалите его и добавите снова, он будет выглядеть так, как ожидалось.   -  person Filip Radelic    schedule 16.09.2014
comment
Несколько дней назад я подал радар для этой проблемы: openradar.appspot.com/radar?id=5308200412774400   -  person Tomasz Szulc    schedule 25.09.2014
comment
У меня была такая же проблема, и мне помогло создание подкласса MPVolumeView и переопределение одного метода - (CGRect)volumeSliderRectForBounds:(CGRect)bounds { return bounds; }. К сожалению, это скорее обходной путь. И я не проверял, как это работает, если кнопка маршрута (например, для трансляции) должна быть представлена. С другой стороны, Apple больше не показывает эту кнопку в приложениях, поскольку она представлена ​​в Центре управления начиная с iOS7, поэтому я также не показываю ее, и для меня это решение работает хорошо.   -  person Anastasia    schedule 21.11.2014


Ответы (2)


Один из возможных способов устранить это поведение — создать подкласс MPVolumeView и выполнить некоторую дополнительную работу после [super layoutSubviews].

- (void)layoutSubviews
{
    [super layoutSubviews];

    [self cg_recursiveRemoveAnimationsOnView:self];
}

- (void)cg_recursiveRemoveAnimationsOnView:(UIView *)view
{
    [view.layer removeAllAnimations];
    for (UIView *subview in view.subviews) {
        [self cg_recursiveRemoveAnimationsOnView:subview];
    }
}

Это удалит все вставленные анимации. Так что убедитесь, что это то, что вы хотите, так как это довольно излишество. Можно также просто удалить анимации position и bounds (см. removeAnimationForKey:).

person Patrik    schedule 10.04.2015
comment
Почему бы не использовать UIView.performWithoutAnimation - намного проще - person Leo Natan; 10.04.2015
comment
Вы имеете в виду запаковать [super layoutSubviews] в -performWithoutAnimation? Это не сработало, так как анимация создается где-то еще, а также не каждый слой в MPVolumeView имеет делегата UIView. - person Patrik; 13.04.2015
comment
Он должен выполнять ту же функцию, что и ваш метод. Если нет, то это анимация CA, что еще более своеобразно. - person Leo Natan; 13.04.2015
comment
Почему это должно выполнять ту же операцию? Каждая анимация — это анимация CA (несмотря на такие фреймворки, как pop). Будет ли работать -performWithoutAnimation, зависит только от того, как добавлена ​​анимация. - person Patrik; 14.04.2015
comment
Если анимация поставлена ​​в очередь где-то внутри супервызова макета, она будет отброшена из-за performWithoutAnimation:. Если он не отбрасывается, это означает, что он либо был поставлен в очередь раньше, либо является анимацией CA напрямую. - person Leo Natan; 14.04.2015

Я подтверждаю, что эта проблема все еще существует в iOS 8. Обходной путь, предоставленный Анастасией в одном из комментариев выше (с переопределением volumeSliderRectForBounds), кажется, работает, но только когда кнопка маршрута отсутствует. Когда он присутствует, ползунок перекрывает кнопку маршрута, и его больше нельзя нажать.

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

- (CGRect)volumeSliderRectForBounds:(CGRect)bounds
{
    if (self.showsRouteButton) {
        NSInteger spacer = 10; /* Space between Route button and Volume slider */
        CGRect routeButtonRect = [self routeButtonRectForBounds:bounds];
        bounds.size.width -= (routeButtonRect.size.width + spacer);
    }
    return bounds;
}

Мне не нравится жестко задавать значение разделителя, но я не смог найти, как его рассчитать динамически.

person tgebarowski    schedule 03.02.2015