Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
888 views
in Technique[技术] by (71.8m points)

xamarin - How to set height of view with FluentLayout

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...