0

I am seeing an unexpected initial condition when I set layer opacity multiple times within a UIView.animate block:

movingView.frame = CGRect(x: 120, y: 120, width: 100, height: 100)
movingView.backgroundColor = UIColor.blue

opacityView.backgroundColor = UIColor.red
opacityView.layer.opacity = 0.5

DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
    UIView.animate(withDuration: 3.0) {
        opacityView.layer.opacity = 0
        opacityView.layer.opacity = 1

        movingView.frame = CGRect(x: 10, y: 120, width: 100, height: 100)
        movingView.frame = CGRect(x: 190, y: 120, width: 100, height: 100)
    }
}

When this code is run in the playground, the blue (bottom) square animates from the middle of the view to the right edge, as expected, even though the frame is initially set to the left hand position, only the last value is used in the animation.

The red square however, does not animate from 0.5 opacity directly to 1.0. It first jumps to 0.0 opacity with no animation before then animating to 1.0 opacity.

Obviously this is a contrived case, but I ran into this when animating only one of a group of elements, I set all elements to opacity 0, then set the one I wished to be visible to animate to opacity 1. But this did not give the expected animations. I was able to work around this by removing the one I wished to be visible from list of all items.

But I am curious and would like to understand what is occurring here, and why the opacity behaviour differs from animating frame values, and if there is another cleaner way to work around this.

============================================

For clarity, I understand what will make this work, but this is a contrived example, in order to make it work in the real world, my code becomes unnecessarily more complex. I want to know why it is exhibiting this behaviour, and why it is different from animating the frame.

Daniel Brotherston
  • 1,954
  • 4
  • 18
  • 28

1 Answers1

0

If I understand what you expect, you want to animate your view from 0.5 to 0 then to 1. In order to do that you should use two animations. Fire the first one then add a completion handler to fire the second one.

Also, you can try to work with alpha instead of opacity.

I hope it helps.

Poulpy
  • 134
  • 8
  • No, I expect it to animate from 0.5 to 1.0 without ever hitting the intermediate value of 0.0 (effectively it is ignored), as this is the same behaviour I observe for frame animations. – Daniel Brotherston Jul 09 '17 at 22:18
  • ok so in that case why do you set your opacity to 0.0 at the beginning of the animation ? Remove this line and it should work fine. – Poulpy Jul 09 '17 at 22:19
  • Again, this is a contrived example, I can easily fix the problem, and have already done so in my code. It is not quite as simple when I am animating many objects, and am simply passed the list of objects, as well as the one object I want visible (so set all objects to 0.0, then the one visible one to 1.0). I am still interested in knowing why this occurs and if it is possible to overcome it in a less complex way. – Daniel Brotherston Jul 09 '17 at 22:23
  • I think this is because you try to animate several element at the same time. Because an animation occurs in his thread, multiple threads try to act on the same variable at the same time which can result in crash or weird behaviors. I will delete my answer because it is not suitable for your question. I hope you will find the answer. – Poulpy Jul 09 '17 at 22:34