问题描述
我在 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
是做什么的?我总是需要它以便约束起作用,但不知道它究竟做了什么。
解决方法
我想出了一个技巧。我子类 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);
}
}