3
votes

Im relatively new to UIView animations and made a simple up/down animation of a "infoView"s frame.

enter image description here

The dark blue area is touchable and toggle the animation which works fine so far.

The problem is only the change of the TEXT from the UILabel on the top right. If I change content of the Label before, after or in the completion block of the animation the animation always fails. -> then it doesn't animate up anymore... it seems to blink one time. I don't know what's the problem here....

some code: i save the two frame positions for the animation:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        infoViewRectNotVisible = infoView.frame
        infoViewRectVisible = CGRect(x: infoView.frame.minX, y: searchBar.frame.minY, width: infoView.frame.width, height: infoView.frame.height)
 }

and i simply animate the infoView up and down:

@IBAction func infoButtonPressed(_ sender: Any) {
        infoIsVisible = !infoIsVisible

        showHideLabel.text = infoIsVisible ? "hide Info" : "show Info"

        print(infoView.frame)
        print(infoViewRectVisible)
        print(infoViewRectNotVisible)

        UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut, animations: {
            self.infoView.frame = self.infoIsVisible ? self.infoViewRectVisible : self.infoViewRectNotVisible
        })
}

If i comment showHideLabel.text = infoIsVisible ? "hide Info" : "show Info" out, the animation works as accepted otherwise it dont animate up anymore

The infoIsVisible Bool and the saved frames (infoViewRectVisible & infoViewRectNotVisible) are always correct.

I have tried:

  • .setNeedsLayout(), .layoutIfNeeded()
  • set text in the completion block of the animation
  • .translatesAutoresizingMaskIntoConstraints to false
  • ....

I really dont know why i cant change the text - or do I completely misunderstand something?

Thank you for your help!

1
Do you use Autolayout/SnapKit to position the label inside of the blue view?ctomato
Hey, yeah the label is positioned top, right with Autolayout.Appygix
So when you change the text the label changes its frame to intrinsicContentSize to fit the new content. After that it probably implicitly calls setNeedsLayout, so I guess Autolayout basically interferes with your manual UIView animation. Could you try setting fixed size constraints for the label and try again?ctomato
Instead of manually changing the frame of infoView, try setting up its top constraint, change its constant property based on infoIsVisible and then call infoView.setNeedsLayout() inside the UIView.animate... block.ctomato
The problem is you are mixing constraints with setting frame properties. You should only do one or the other. Animate with constraints instead.LGP

1 Answers

0
votes

You don't need to animate frames to achieve the desired result. You could just animate proper view transforms instead:

let yTranslation = CGAffineTransform(
    translationX: 0.0,
    y: infoView.frame.height - searchBar.frame.height
)

UIView.animate(
    withDuration: 0.3,
    delay: 0,
    options: .curveEaseInOut,
    animations: {
        self.infoView.transform = self.infoIsVisible ? yTranslation : .identity
    }
)