UISlider animation skipped on iOS 7

I have a slider that works like 2 sliders, in accordance with the sound played - when 1 type of sound is turned off (some kind of voice guidance), music is played, and the slider controls the volume of the music.

When changing roles, the slider changes its position in accordance with its role (leadership is the highest in the presentation, music is lower) and adjusts its value (volume) to the stored volume value for this type of sound (leadership sound or music sound).

The type of effect I was looking for is

  • Move the slider to a new location using [UIView animateWithDuration]
  • When the slider reaches its location, change its value to reflect the volume, again using [UIView animateWithDuration] .

First, I wrote it like this:

 [UIView animateWithDuration:0.3 animations:^{self.volumeSlider.frame = sliderFrame;} completion:^(BOOL finished){ [UIView animateWithDuration:0.3 animations:^{self.volumeSlider.value = newValue;} ]; }]; 

Which worked very well in the iOS 6 simulator (using Xcode 4.6.3), but when changing on my phone, running iOS 7, the slider changed its position, and then the value of the slider moved to a new value. The same problem arose again when running in the iOS 7 simulator that ships with Xcode 5, so I assume this is an iOS 7 issue.

I conducted several experiments, all with different results:

  • I tried to set the volume using "[UIView animateWithDuration: 0.3 delay: 0.3 options: animations: completion:]", which doesnโ€™t mean the completion part, but the same thing happened.
  • When placing only 2 animations one after another (each of them, as a separate animation, each without delay, one after the other), the result will depend on the order of the animation.

     [UIView animateWithDuration:0.3 animations:^{self.volumeSlider.value = newValue;}]; [UIView animateWithDuration:0.3 animations:^{self.volumeSlider.frame = sliderFrame;}]; 

Both the slider and its value will move together , both animated, and

  [UIView animateWithDuration:0.3 animations:^{self.volumeSlider.frame = sliderFrame;}]; [UIView animateWithDuration:0.3 animations:^{self.volumeSlider.value = newValue;}]; 

Move the position of the slider, and then change its value without animation.

  • I tried calling the second animation via

     [self performSelector:@selector(animateVolume:) withObject:nil afterDelay:0.3]; 

And again, the shift of the slider, and then the value changed immediately.

WHY HE IT WHY ??? If this helps, this is a slider description, BEFORE the first animation -

 <UISlider: 0xcc860d0; frame = (23 156; 276 35); autoresize = RM+BM; layer = <CALayer: 0xcc86a10>; value: 1.000000> 

And after the first animation ended -

 <UISlider: 0xcc860d0; frame = (23 78; 276 35); autoresize = RM+BM; animations = { position=<CABasicAnimation: 0xbce5390>; }; layer = <CALayer: 0xcc86a10>; value: 0.000000> 

Pay attention to the animation section, which should not be present yet (the description is written from [self animateVolume], which is called with a delay of 0.3 seconds).

I know this is a strange problem, but I would really like to help with it.

Thanks :) Dan

UPDATE

As Christopher Mann suggested, changing the value in the UIView: animationWithDuration is not an official way to use it, and the correct way would be to use the UISlider setValue: animated.

However, for people who will encounter such a problem in the future, it seems that iOS 7 has some difficulties with this method, so in some cases it will not be animated (I think that it will not be animated if the project was started in Xcode < 5). The problem and its solution are described here .

My code that solved this problem:

 [UIView animateWithDuration:0.3 animations:^{self.volumeSlider.frame = sliderFrame;} completion:^(BOOL finished){ [UIView animateWithDuration:1.0 animations:^{ [self.volumeSlider setValue:newValue animated:YES]; }]; currentSliderMode = mode; }]; 
+7
cocoa-touch xcode ios7 uiview uiviewanimation
source share
1 answer

If you want to animate the change in the value of the slider, you should use setValue:animated: instead of setting the .value value directly. Changing the value of volumeSlider.value inside a UIView animation block is likely to interfere with the animation.

+7
source share

All Articles