swiftanimationpositioncompletionchained

animation not moving upwards in chaining animation in swift


I want my swift code to follow the gif I created. What is going is after the first animation there is not any change of the position. Like the gif I created it should first move down then move up again. I tried multiplying by the negative -0.15 thinking it would go in the north direction. Right now it is not having a effect.

enter image description here

  UIView.animate(withDuration: 1, animations: {
        self.block1.frame = CGRect(x: 0, y: self.view.frame.height * 0.15, width: self.view.frame.width, height: self.view.frame.height * 0.1)
        self.block1.center = self.view.center
    }) { done in

        /// first animation finished, start second
        if done {
            UIView.animate(withDuration: 1, animations: {
                
                self.block1.frame = CGRect(x: 0, y: self.view.frame.height * (-0.15), width: self.view.frame.width, height: self.view.frame.height * 0.1)
                
                
                self.block1.center = self.view.center
                
            })
        }
    }

Solution

  • Start by getting rid of self.block1.center = self.view.center as you're making the centre point of the block the same as the view in both cycles.

    self.view.frame.height * (-0.15) is setting an absolute position out side of the view, not sure if that's intentional, but you might want to be aware of it. Instead, if you only wanted to move a given distance, say the height of the view, you should be using a relative position, such as block1.frame.origin.y -= block.frame.size.height (probably a much easier way to say that, but you get the idea)

    So I created a really quick Playground, made up some values and got a "sort of" bouncy, returny thing going as an example

    Quick example

    import UIKit
    import XCPlayground
    
    let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 300.0, height: 600.0))
    // XCPShowView("container", view: container)  // -> deprecated
    
    let block1 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: (view.frame.width) / 2, height: 150))
    block1.backgroundColor = UIColor.green
    block1.center.x = view.center.x
    view.addSubview(block1)
    
    UIView.animate(withDuration: 1, animations: {
        let y = view.frame.height * 0.15
        print(y)
        block1.center.y = view.center.y
    }) { done in
        print("Done = \(done)")
        /// first animation finished, start second
        if done {
            UIView.animate(withDuration: 1, animations: {
                block1.frame.origin.y = 0
            })
        }
    }
    
    XCPlaygroundPage.currentPage.liveView = view
    

    Caveat: There's probably a really neat and easy way to do "auto reversal" style animations using CALayer and I'd be keen to see other examples presenting the same concept