iosswiftxamarin.iosvisual-format-language

How to properly align two buttons horizontally and vertically


I am working with Visual Format language for the first time an I am struggling to programmatically align two buttons horizontally and then align these two buttons vertically.

My current approach is to put the two buttons into some container view, align them horizontally in this container, and then vertically align this container view in the main view but this has the effect of horizontally aligning my buttons in one location, and then vertically aligning my container view elsewhere.

Here is my current approach:

var views = new NSMutableDictionary();

viewDidLoad():

views.Add(new NSString("questionTextView"), QuestionTextView);

...
UIButton button1 = new UIButton();
UIButton button2 = new UIButton();
UIView containerView = new UIView(new CGRect(0, 0, 500, 100));

views.Add(new NSString("containerView"), containerView);
containerView.TranslatesAutoresizingMaskIntoConstraints = false;
View.AddSubview(containerView);

var textViewCenter = NSLayoutConstraint.FromVisualFormat(
    format: "|-[containerView]-|",
    formatOptions: NSLayoutFormatOptions.AlignAllCenterX,
    metrics: null,
    views: views
);
NSLayoutConstraint.ActivateConstraints(textViewCenter);

addButton(button1, new NSString("button1"), containerView);
addButton(button2, new NSString("button2"), containerView);
addQuestionViewContraints();
addTwoButtonConstraints();
adjustQuestionView();

Relevant functions:

public void addButton(UIButton button, NSString buttonIdentifier, UIView containerView){
        button = new UIButton(new CGRect(0, 0, 200, 100));

        button.TranslatesAutoresizingMaskIntoConstraints = false;
        button.SetTitle(buttonText, UIControlState.Normal);

        containerView.AddSubview(button);
        views.Add(buttonIdentifier, button);
}
public void addTwoButtonConstraints()
{
        var twoButtonHorizontalConstraints = NSLayoutConstraint.FromVisualFormat(
            format: "|-[button1]-[button2]-|",
            formatOptions: NSLayoutFormatOptions.AlignAllTop,
            metrics: null,
            views: views
        );
        NSLayoutConstraint.ActivateConstraints(twoButtonHorizontalConstraints);

        var verticalAlignment = NSLayoutConstraint.FromVisualFormat(
            format: "V:|-[questionTextView]-(>=100)-[containerView(>=100)]-(>=50)-|",
            formatOptions: NSLayoutFormatOptions.AlignAllCenterX,
            metrics: null,
            views: views
        );
        NSLayoutConstraint.ActivateConstraints(verticalAlignment);

}
public void addQuestionViewContraints(){
        QuestionTextView.TranslatesAutoresizingMaskIntoConstraints = false;
        var textViewCenter = NSLayoutConstraint.FromVisualFormat(
            format: "|-[questionTextView]-|",
            formatOptions: NSLayoutFormatOptions.AlignAllCenterX,
            metrics: null,
            views: views
        );
        NSLayoutConstraint.ActivateConstraints(textViewCenter);
}

My guess would be that since the container view ends up getting aligned properly, and since the buttons get properly aligned horizontally, my issue lies with my buttons not properly becoming part of the containerView. Thanks for any insight.


Solution

  • You have to use stack view for this:

    //Button first View
    let buttonFirst = UIButton()
    buttonFirst.backgroundColor = UIColor.blue
    buttonFirst.heightAnchor.constraint(equalToConstant: 120.0).isActive = true
    imageView.widthAnchor.constraint(equalToConstant: 120.0).isActive = true
    
    //Button second View
    let buttonSecond = UIButton()
    buttonSecond.backgroundColor = UIColor.red
    buttonSecond.heightAnchor.constraint(equalToConstant: 120.0).isActive = true
    buttonSecond.widthAnchor.constraint(equalToConstant: 120.0).isActive = true
    
    
    //Stack View
    let stackView   = UIStackView()
    stackView.axis  = UILayoutConstraintAxis.vertical
    stackView.distribution  = UIStackViewDistribution.equalSpacing
    stackView.alignment = UIStackViewAlignment.center
    stackView.spacing   = 16.0
    
    stackView.addArrangedSubview(buttonFirst)
    stackView.addArrangedSubview(buttonSecond)
    stackView.translatesAutoresizingMaskIntoConstraints = false
    
    self.view.addSubview(stackView)