如何使用 mvvmcross fluentLayout 修改约束



我象征性地把头发拔掉了。我从这篇文章"http://gregshackles.com/fluentlayout-2-5/"中读到,FluentLayout 现在支持约束编辑/删除,但它似乎对我不起作用。我的方案是在单击按钮时切换 UIView 中文本字段的可见性。

我已经尝试了以下方法。

A. 修改高度约束

var height = isVisible ? textfield.Height().EqualTo(0) : textfield.WithSameHeight(textfieldContainer).Multiplier(1 / 3);
textfieldContainer.Add(textfield);
textfieldContainer.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
textfieldContainer.AddConstraints(
textfield.WithSameLeft(textfieldContainer).Plus(12),
textfield.WithSameTop(textfieldContainer).Plus(24),
textfield.WithSameWidth(textfieldContainer),
height
);

B. 使用 SetActive(false) - 出于绝望而尝试过这个

textfieldContainer.Add(textfield);
textfieldContainer.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
textfieldContainer.AddConstraints(
textfield.WithSameLeft(textfieldContainer).Plus(12).SetActive(!isVisible),
textfield.WithSameTop(textfieldContainer).Plus(24).SetActive(!isVisible),
textfield.WithSameWidth(textfieldContainer).SetActive(!isVisible),
textfield.WithSameHeight(textfieldContainer).WithMultiplier(1 / 4).SetActive(!isVisible)
);

预期成果

文本字段应可见,具体取决于可见性

实际结果

文本字段的高度永远不会改变,因此始终可见

我的猜测是,您的height变量在页面生命周期中设置一次,之后不会发生变化。实现所需内容的一种方法如下:

首先,将按钮单击绑定到更改ViewModelboolean状态的命令,以便在单击按钮时boolean的值发生变化:

bindingSet.Bind(yourButton).To(vm => vm.YourCommand);

MvxCommand _yourCommand;
public MvxCommand YourCommand
=> _yourCommand ?? _yourCommand = new MvxCommand(ReverseMyBool);
void ReverseMyBool()
{
YourBoolean = !YourBoolean;
}

如有必要,请在构造ViewModel期间将YourBoolean设置为 true,具体取决于您是否希望在页面加载期间隐藏字段。现在,ViewModel属性对于是否应隐藏UITextField保持准确的真/假状态,请将UITextField本身绑定以Hidden布尔值(您可能需要使用值转换器来反转值 - 如果Hidden为 true,则视图不可见):

bindingSet.Bind(textfield).For(c => c.Hidden).To(vm => vm.YourBoolean);

接下来,创建与这两种情况相关的FluentLayout变量(您的视图可见和隐藏),并同时应用它们:

var textFieldWithOneThirdContainerHeight = textfield.WithSameHeight(textFieldContainer).WithMultiplier(1f /3f);
var textFieldWithZeroHeight = textField.Height().EqualTo(0f);
textfieldContainer.AddConstraints(textFieldWithOneThirdContainerHeight, textFieldWithZeroHeight, /*other constraints here*/);

最后,将Active约束绑定到ViewModel上的boolean- 请注意,需要使用转换器来反转:

bindingSet.Bind(textFieldWithOneThirdContainerHeight).For(c => c.Active).To(vm => vm.YourBoolean).WithConversion(new ReverseBooleanValueConverter());
bindingSet.Bind(textFieldWithZeroHeight).For(c => c.Active).To(vm => vm.YourBoolean);

ReverseBooleanValueConverter看起来像这样:

public class ReverseBooleanValueConverter: MvxValueConverter<bool, bool>
{
protected override bool Convert(bool value, Type targetType, object parameter, CultureInfo culture) 
=> !value;
}

YourBoolean为真时,您的UITextField应该是不可见的,并且应该具有0f的高度。当YourBoolean为假时,它应该是可见的,并且应该有其容器高度的三分之一。

最新更新