mihai mimi
mihai mimi

Reputation: 133

How to position a view with anchors to a view that has just finished animating?

A view that is anchored to the centre of the screen on both axis is animated (transitions) to a new location with a new size. When the animation finishes, the completion block calls an animation to occur on another view, which has its leading anchor constrained some distance away from the trailing anchor of the view that first animated. The problem that I have is that I do not know the solution of making the second view's animation take into account the new frame of the view that has just finished. The second view needs to end up to the right and centred on the Y to the first view.

Every thing that I have tried has the same result: the second view takes into account the position of the first view before it animated to its new location and size. How do I update the constraints for it? I have tried with NSLayoutConstraint variables, updating the constraints, but nothing works. Relevant code listed, thank you.

func setupViews() { // called in viewDidLoad
        view.addSubview(programIcon)
        view.addSubview(programTitle)
        let iconConstraints = [
        programIcon.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        programIcon.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        programIcon.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -37.5),
        programIcon.heightAnchor.constraint(equalTo: programIcon.widthAnchor)
        ]
        NSLayoutConstraint.activate(iconConstraints)

        titleHiddenX = programTitle.leadingAnchor.constraint(equalTo: view.trailingAnchor)
        titleHiddenX.isActive = true
        titleHiddenY = programTitle.topAnchor.constraint(equalTo: view.topAnchor) // could do without?
        titleHiddenY.isActive = true

        titleVisibleX = programTitle.leadingAnchor.constraint(equalTo: programIcon.trailingAnchor, constant: 10)
        titleVisibleX.isActive = false
        titleVisibleY = programTitle.centerYAnchor.constraint(equalTo: programIcon.centerYAnchor)
        titleVisibleY.isActive = false
        } 
    @objc func animateIcon() {
        if animationHasBeenShown {
            print("animation has beed shown already")
        } else {
            //I have removed the math part as its not relevant here.

            UIView.animate(withDuration: 0.5, animations: {
                self.programIcon.transform = scale.concatenating(translation)
            }) { (true) in
                self.programTitle.setNeedsUpdateConstraints()
                self.animateElementsOnScreen()
                print("icon frame \(self.programIcon.frame)")
            }
        }
    }
   func animateElementsOnScreen() {
        UIView.animate(withDuration: 0.5, animations: { // this needs to change.

            self.titleHiddenX.isActive = false
            self.titleHiddenY.isActive = false
            self.titleVisibleX.isActive = true
            self.titleVisibleY.isActive = true
            self.view.layoutIfNeeded()
        }) { (true) in
            print("title frame \(self.programTitle.frame)")
        } // and so on, more views animating.

Upvotes: 0

Views: 319

Answers (1)

DonMag
DonMag

Reputation: 77423

From Apple's docs (https://developer.apple.com/documentation/uikit/uiview/1622459-transform):

In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout calculates a view’s alignment rectangle based on its untransformed frame.

If you want to move or scale a view AND maintain its auto-layout / constraints properties, you need to animate a change to the view's constraints instead of applying a .transform.

Upvotes: 1

Related Questions