Search code examples
iosuiviewcontrollerxamarin.iosuibuttonautolayout

iOS UI Button Doesn't Respect TopAnchor and HeightAnchor


I'm trying to create a UIViewController with two buttons that are stacked vertically on the bottom of the UIView (Like the iOS action sheet look on an iPod). For some reason, my top button's top anchor is perpetually stuck to the top of the UIViewController.

I've got the bottom button to move to the correct location at the bottom of the controller. I achieved this by setting the second button's top anchor like so:

NSLayoutConstraint.ActivateConstraints(new[] { this.secondButton.TopAnchor.ConstraintEqualTo(this.View.SafeAreaLayoutGuide.BottomAnchor, -(this.secondButton.Frame.Height + 30f)) });
this.secondButton.UpdateConstraints();

I tried to do something similar for the first button as well.I've gone through 2 cases where the top button is stuck anchored to the top.

  1. Set top anchor with the same type of logic as the second button is set

    NSLayoutConstraint.ActivateConstraints(new[] { 
    this.firstButton.HeightAnchor.ConstraintEqualTo(this.firstButton.Frame.Height), 
    this.firstButton.TopAnchor.ConstraintEqualTo(this.View.SafeAreaLayoutGuide.BottomAnchor, -(2 * this.secondButton.Frame.Height + 60f)) });
    this.firstButton.UpdateConstraints();
    

Result:

Top Anchor Stuck 1

  1. Set the bottom anchor for based on button two by swapping TopAnchor line above to this

    this.firstButton.BottomAnchor.ConstraintEqualTo(this.buttonTwo.TopAnchor, -30f)
    

Result: Top Anchor Stuck 2

Regardless of how I set the height anchor and top / bottom anchors for button one, it won't stop anchoring to the very top of the viewcontroller. I've made sure that TranslatesAutoresizingMaskIntoConstraints have been set to false for both buttons, and I checked that there were no previous constraints on the two buttons. Any insight? Thanks!


Solution

  • We need to see all the Constraints in your project to find out the cause and solution. I guess you don't remove the old constraints when adding a new Constraint.

    I wrote a example to you to fix two buttons in the bottom:

       public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();
            // Perform any additional setup after loading the view, typically from a nib.
    
    
            UIButton firstButton = new UIButton(UIButtonType.System);
            firstButton.SetTitle("first", UIControlState.Normal);
            firstButton.Layer.BorderColor = UIColor.Green.CGColor;
            firstButton.Layer.BorderWidth = 1.5f;
            View.Add(firstButton);
    
            UIButton secondButton = new UIButton(UIButtonType.System);
            secondButton.SetTitle("second", UIControlState.Normal);
            secondButton.SetTitleColor(UIColor.Red,UIControlState.Normal);
            secondButton.Layer.BorderColor = UIColor.Yellow.CGColor;
            secondButton.Layer.BorderWidth = 1.50f;
            View.Add(secondButton);
    
            firstButton.TranslatesAutoresizingMaskIntoConstraints = false;
            secondButton.TranslatesAutoresizingMaskIntoConstraints = false;
    
            View.AddConstraints(new[] {
                secondButton.HeightAnchor.ConstraintEqualTo(60),
                secondButton.BottomAnchor.ConstraintEqualTo(this.View.SafeAreaLayoutGuide.BottomAnchor,0),
                secondButton.LeftAnchor.ConstraintEqualTo(View.LeftAnchor,20),
                secondButton.RightAnchor.ConstraintEqualTo(View.RightAnchor,-20),
            });
    
            View.AddConstraints(new[] {
                firstButton.HeightAnchor.ConstraintEqualTo(60),
                firstButton.BottomAnchor.ConstraintEqualTo(secondButton.TopAnchor,-30),
                firstButton.LeftAnchor.ConstraintEqualTo(View.LeftAnchor,20),
                firstButton.RightAnchor.ConstraintEqualTo(View.RightAnchor,-20),
            });
        }
    

    And here is the result:

    enter image description here