Bowcaps
Bowcaps

Reputation: 127

Layout Anchors in Swift 4

I am endeavoring to update / streamline my code pertaining to Auto Layout vs NSConstraints, however it seems to be baffling me for now.

I have some Swift 3 code which slides in a UIView on the tap of a button, however the UIView is controlled with NSconstraints and works fine. -

@IBAction func rightFlyOutButton(_ sender: Any) {
        if (rightFlyOutShowing) {
            if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
                leftFlyOutLeadingConstraint.constant = 25
            } else {
                leftFlyOutLeadingConstraint.constant = 15
            }
            rightFlyOutTrailingConstraint.constant = rightFlyOut.frame.width * 0.93
            UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
        } else {
            if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
                rightFlyOutTrailingConstraint.constant = 25
            } else {
                rightFlyOutTrailingConstraint.constant = 15
            }
            UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
        }
        rightFlyOutShowing = !rightFlyOutShowing
    }

Trying to use AutoLayout and Layout Anchors, I cam up with this -

@IBAction func rightFlyOutButton(_ sender: Any) {
        rightFlyOut.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        rightFlyOut.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.93).isActive = true
        UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
    }

This returns a multitude of errors -

[LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x6000000949b0 h=-&& v=-&& FasteM.UIViewX:0x7fed7140c600.width == 0.500741*UIView:0x7fed7161d760.width + 150.222   (active)>",
    "<NSLayoutConstraint:0x6000000900e0 FasteM.UIViewX:0x7fed7140c600.width == 0.93*UIView:0x7fed7161d760.width   (active)>",
    "<NSLayoutConstraint:0x600000095a90 'UIView-Encapsulated-Layout-Width' UIView:0x7fed7161d760.width == 375   (active)>"
)

My logic is I am anchoring the right edge of the view to the superview and specifying the width of the actual view (i.e. 93% of the superview.

I'm sure this is a simple error that i'm missing, but I would appreciate any pointers in the right direction.

TIA

Upvotes: 0

Views: 880

Answers (2)

Bowcaps
Bowcaps

Reputation: 127

I've had a bash around with this problem and finally came up with a working solution -

Firstly create a variable :

var LeftFlyOutConstraint: NSLayoutConstraint?

Then use the following code in viewDidLoad() :

leftFlyOut.translatesAutoresizingMaskIntoConstraints = false    
LeftFlyOutConstraint = leftFlyOut.trailingAnchor.constraint(equalTo: view.leadingAnchor, constant: 35)
    LeftFlyOutConstraint?.isActive = true

And finally the button :

@IBAction func leftFlyOutButton(_ sender: Any) {
        if (leftFlyOutShowing) {
            LeftFlyOutConstraint?.isActive = false
                LeftFlyOutConstraint = leftFlyOut.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -40)
            LeftFlyOutConstraint?.isActive = true
            UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
        } else {
            LeftFlyOutConstraint?.isActive = false
            LeftFlyOutConstraint = leftFlyOut.trailingAnchor.constraint(equalTo: view.leadingAnchor, constant: 35)
            LeftFlyOutConstraint?.isActive = true
            UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
        }
        leftFlyOutShowing = !leftFlyOutShowing
    }

And no reported errors.

Upvotes: 0

Shehata Gamal
Shehata Gamal

Reputation: 100533

the problem with the second approach is that for every click it will create other constraints which will make a conflict with the old same ones , so you should create those constraints any where , get a reference to them and change their constants as you did in first right approach

Upvotes: 1

Related Questions