0

I am using FluentLayout with my Xamarin.iOS project. I created a view:

public class SignInView : UIView
{
    private const int headerSpacing = 20;
    private const int textFieldSpacing = 10;
    private const int textFieldButtonSpacing = 15;
    private const int buttonSpacing = 10;
    private const int textFieldHeight = 50;

    public SignInView()
    {
        ConstructView();
    }

    private void ConstructView()
    {
        var signInLabel = new UILabel() { Text = "sign in" };
        var usernameTextField = new UITextField() { Placeholder = "enter username" };
        var passwordTextField = new UITextField() { Placeholder = "enter password" };
        var signInButton = new UIButton();
        var createAccountButton = new UIButton();

        signInButton.SetTitle("sign in", UIControlState.Normal);
        createAccountButton.SetTitle("create account", UIControlState.Normal);

        AddSubviews(signInLabel, usernameTextField, passwordTextField, signInButton, createAccountButton);

        this.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

        this.AddConstraints(
            signInLabel.WithSameTop(this),
            signInLabel.WithSameCenterX(this),

            usernameTextField.Below(signInLabel, headerSpacing),
            usernameTextField.WithSameWidth(this),
            usernameTextField.Height().GreaterThanOrEqualTo(textFieldHeight),

            passwordTextField.Below(usernameTextField, textFieldSpacing),
            passwordTextField.WithSameWidth(this),
            passwordTextField.Height().GreaterThanOrEqualTo(textFieldHeight),

            signInButton.Below(passwordTextField, textFieldButtonSpacing),
            signInButton.WithSameWidth(this),

            createAccountButton.Below(signInButton, buttonSpacing),
            createAccountButton.WithSameWidth(this)
        );

        BackgroundColor = UIColor.Red;
    }
}

When I place SignInView in my view, I see everything correctly, but the background isn't red because the height is zero, and nothing is clickable for the same reason. Is there a way to set the height in SignInView to be the bottom of createAccountButton?

By the way, what does SubviewsDoNotTranslateAutoresizingMaskIntoConstraints do? I always need it so that the constraints work, but don't know what it does exactly.

Drake
  • 2,679
  • 4
  • 45
  • 88
  • Hi, it seems `FluentLayout` not provides the way to modify `Height` of View. – Junior Jiang Jan 06 '21 at 06:12
  • Where would you suggest to set the height of my view? Is there an event that gets triggered when the constraints have been applied? Or a method that I can override to set the height there? – Drake Jan 06 '21 at 07:20
  • If you have to use `FluentLayout`, it seems you only can have a try with adjusting Control height by content. You could contact the author to check whether it can add `Height`. Generally, iOS control use `new CGRect(...)` to set `Height`. You also can have a try with this to check. Could have a look at this discussion: https://stackoverflow.com/questions/49295545/adjust-uilabel-height-by-content-in-xamarin-ios – Junior Jiang Jan 06 '21 at 07:26

1 Answers1

0

I figured out a trick. I sub class UIButton and put an event handler to notify when the constraints have been updated so my SignInView can update its constraints with the appropriate height.

public class ConstraintsButton : UIButton
{
    public event EventHandler ConstraintsUpdated;

    public override void UpdateConstraints()
    {
        base.UpdateConstraints();
        
        ConstraintsUpdated?.Invoke(null, EventArgs.Empty);
    }
}

public class SignInView : UIView
{
    private const int headerSpacing = 20;
    private const int textFieldSpacing = 10;
    private const int textFieldButtonSpacing = 15;
    private const int buttonSpacing = 10;
    private const int textFieldHeight = 50;
    private const int buttonHeight = 50;

    private ConstraintsButton _createAccountButton;
    private FluentLayout _heightConstraint;

    public SignInView()
    {
        ConstructView();
    }

    private void ConstructView()
    {
        var signInLabel = new UILabel() { Text = "sign in" };
        var usernameTextField = new UITextField() { Placeholder = "enter username" };
        var passwordTextField = new UITextField() { Placeholder = "enter password" };
        var signInButton = new UIButton();

        _createAccountButton = new ConstraintsButton();
        _createAccountButton.ConstraintsUpdated += CreateAccountButton_ConstraintsUpdated;

        signInButton.SetTitle("sign in", UIControlState.Normal);
        _createAccountButton.SetTitle("create account", UIControlState.Normal);

        AddSubviews(signInLabel, usernameTextField, passwordTextField, signInButton, _createAccountButton);

        this.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

        this.AddConstraints(
            signInLabel.WithSameTop(this),
            signInLabel.WithSameCenterX(this),

            usernameTextField.Below(signInLabel, headerSpacing),
            usernameTextField.WithSameWidth(this),
            usernameTextField.Height().GreaterThanOrEqualTo(textFieldHeight),

            passwordTextField.Below(usernameTextField, textFieldSpacing),
            passwordTextField.WithSameWidth(this),
            passwordTextField.Height().GreaterThanOrEqualTo(textFieldHeight),

            signInButton.Below(passwordTextField, textFieldButtonSpacing),
            signInButton.WithSameWidth(this),
            signInButton.Height().EqualTo(buttonHeight),

            _createAccountButton.Below(signInButton, buttonSpacing),
            _createAccountButton.WithSameWidth(this),
            _createAccountButton.Height().EqualTo(buttonHeight)
        );

        BackgroundColor = UIColor.Red;
    }

    private void CreateAccountButton_ConstraintsUpdated(object sender, EventArgs e)
    {
        if (_heightConstraint != null)
        {
            this.RemoveConstraints(_heightConstraint);
        }

        _heightConstraint = this.Height().EqualTo(_createAccountButton.Frame.Bottom);

        this.AddConstraints(_heightConstraint);
    }
}
Drake
  • 2,679
  • 4
  • 45
  • 88