1

I want to animate my contentView up from the bottom by modifying contentView's top constraint's constant. It is currently set to screenBounds.height.
contentView also has a bottom constraint at the bottom of the superview.

The following code works fine:

func transition() {
    // animate content view up
    contentViewTopConstraint.constant = contentViewDestinationY // CGFloat value: 50
    
    UIView.animate(withDuration: 0.6, animations: {
        // apply changes
        self.view.layoutIfNeeded()
    })
}

Now, the snippet below does not animate (but the view disappears):

@objc func dismissTransition() {
    // animate content view down
    contentViewYConstraint.constant = screenBounds.height // ~ 834 on regular iPads
    
    UIView.animate(withDuration: 0.6, animations: {
        // apply changes
        self.view.layoutIfNeeded()
    })
}

Since there's literally no difference in the functions' code, I thought the @objc might interfere with the animation. Since I'm calling dismissTransition() from a UITapGestureRecognizer, I need the tag.
I created a wrapper:

let tap = UITapGestureRecognizer(target: self, action: #selector(_ dismissTransition))

@objc func dismissTransition() {
    dismissTransition()
}

...but that did not change anything.

I noticed that it does animate if I choose a lower value than screenBounds.height: i.e. using 200 animates just fine.
That led me to suspect the bottom constraint to interfere with the animation:

  • I set its priority to 750, whereas the top constraint's priority is at 1000. – no change.

  • I tried to deactivate the bottom constraint outside the animation block before calling layoutIfNeeded in dismissTransition(). – no change.

To be honest, I'm running out of ideas here, so if anyone knows why this is happening, I'd appreciate any guidance.
Thanks!

PS: Xcode 9, iOS 11


Update

I found the cause of this: I use an extension for UIView to easily set the corner radius that looks like this:

func set(corners: UIRectCorner, radius: CGFloat) {
    let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
    let mask = CAShapeLayer()
    mask.path = path.cgPath
    self.layer.mask = mask
}

When commenting out view.set(corners:radius:) (which I call from inside viewDidLayoutSubviews, it doesn't work properly when executed somewhere else), it animates properly.
How can I change the code to not prevent the animation?

Community
  • 1
  • 1
LinusGeffarth
  • 27,197
  • 29
  • 120
  • 174

1 Answers1

0

Finally came to a solution.
As stated in my recent update to my post, I figured the cause for this weird behavior was an extension that was supposed to round my view's corners.
By using the following code provided by @belous in this thread instead, I was able to make it all work, yay!

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
LinusGeffarth
  • 27,197
  • 29
  • 120
  • 174