如何使用 FluentLayout 设置视图高度

How to set height of view with FluentLayout

我在 Xamarin.iOS 项目中使用 FluentLayout。我创建了一个视图:

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;
    }
}

当我将 SignInView 放在我的视图中时,我可以正确地看到所有内容,但背景不是红色,因为高度为零,并且出于同样的原因没有任何内容是可点击的。有没有办法将 SignInView 中的高度设置为 createAccountButton 的底部?

顺便问一下,SubviewsDoNotTranslateAutoresizingMaskIntoConstraints 是做什么的?我总是需要它来使约束起作用,但不知道它到底做了什么。

我想出了一个窍门。我子 class UIButton 并放置一个事件处理程序来通知约束何时更新,以便我的 SignInView 可以用适当的高度更新其约束。

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);
    }
}