In iOS 8 there is a problem or a feature. When MPVolumeView is shown, it's being animated, like expanding from 0 to it's width. How can I fix that behavior? There was no such problem on iOS 7.
-
Yep, this definitely looks like a bug. It only happens first time MPVolumeView instance is added to a superview. If you remove it and add it again, it will just appear like expected. – Filip Radelic Sep 16 '14 at 15:12
-
I filed a radar few days ago for this issue: http://openradar.appspot.com/radar?id=5308200412774400 – Tomasz Szulc Sep 25 '14 at 05:09
-
3I had the same issue and what helped is subclassing MPVolumeView and overriding single method `- (CGRect)volumeSliderRectForBounds:(CGRect)bounds { return bounds; }`. Unfortunately it's rather a workaround though. And I didn't check how does it work if route button (for airplay for example) should be presented. On the other hand, Apple no longer shows this button in apps, as it's presented in the Control Center since iOS7, so I do not show it as well and for me this solution works good. – Anastasia Nov 21 '14 at 13:28
2 Answers
One possible way to remove this behavior is to subclass MPVolumeView and perform some additional work after [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];
}
}
This removes all inserted animations. So be sure that is what you want, since this is quite the overkill. One could also just remove the position
and bounds
animations (see removeAnimationForKey:
).

- 1,117
- 12
- 21
-
-
You mean wrapping `[super layoutSubviews]` with `-performWithoutAnimation`? This didn't work as the animations seem to be created elsewhere and also not every layer within MPVolumeView has a `UIView` delegate. – Patrik Apr 13 '15 at 20:15
-
It should perform a similar function as your method. If not, the animation is a CA animation, which is even more peculiar. – Léo Natan Apr 13 '15 at 20:41
-
Why should this perform the same operation? Every animation is a CA animation (despite of frameworks like pop). If `-performWithoutAnimation` will work just depends on how an animation is added. – Patrik Apr 14 '15 at 12:37
-
If the animation is queued somewhere within the super call to layout, it will be discarded due to `performWithoutAnimation:`. If it is not discarded, it means it was either queued before, or is a CA animation directly. – Léo Natan Apr 14 '15 at 15:27
I confirm that this problem still exists in iOS 8. The workaround provided by Anastasia in one of the comments above (with overriding volumeSliderRectForBounds) seems to work but only when route button is not present. When it is present the slider overlaps the route button and it can no longer be pressed.
I made a simple modification of her solution, maybe someone can use it as a workaround, until Apple fixes that or better solution is provided.
- (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;
}
I don't like hardcoding the spacer value, but I could not find how to calculate it dynamically.

- 1,189
- 11
- 14