如何使用 mvvmcross fluentLayout 修改约束
How to modify a constraint using mvvmcross fluentLayout
我已经比喻地把我的头发拉出来了。我从这篇文章“http://gregshackles.com/fluentlayout-2-5/”中读到,FluentLayout 现在支持约束 editing/removing,但它似乎对我不起作用。我的方案是在单击按钮时切换 UIView 中文本字段的可见性。
我尝试了以下方法。
一个。修改高度限制
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
);
乙。使用 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
变量在页面生命周期中设置了一次,并且在那之后不会发生变化。实现您需要的方法如下:
首先,将您的按钮点击绑定到更改 ViewModel
上 boolean
状态的命令,以便在单击按钮时更改 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
属性 拥有一个准确的 true/false 状态来决定你的 UITextField
是否应该被隐藏,将 Hidden
的 UITextField
本身绑定到布尔值(您可能需要使用 value converter 来反转值 - 如果 Hidden
为真,则视图不可见):
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
为 false 时,它应该是可见的,并且应该是容器高度的三分之一。
我已经比喻地把我的头发拉出来了。我从这篇文章“http://gregshackles.com/fluentlayout-2-5/”中读到,FluentLayout 现在支持约束 editing/removing,但它似乎对我不起作用。我的方案是在单击按钮时切换 UIView 中文本字段的可见性。
我尝试了以下方法。
一个。修改高度限制
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
);
乙。使用 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
变量在页面生命周期中设置了一次,并且在那之后不会发生变化。实现您需要的方法如下:
首先,将您的按钮点击绑定到更改 ViewModel
上 boolean
状态的命令,以便在单击按钮时更改 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
属性 拥有一个准确的 true/false 状态来决定你的 UITextField
是否应该被隐藏,将 Hidden
的 UITextField
本身绑定到布尔值(您可能需要使用 value converter 来反转值 - 如果 Hidden
为真,则视图不可见):
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
为 false 时,它应该是可见的,并且应该是容器高度的三分之一。