我有一个自定义的MvxConvertingTargetBinding,它对绑定的UIView的可见性执行动画(淡入/淡出)。我在UITableViewCell上的一些按钮上使用此绑定。目的是用户点击按钮,模式中的某些规则发生变化,按钮消失(其他按钮出现在其位置)。
绑定在向控件分配绑定值期间捕获 - 这是否是第一次'绑定已被应用。如果它是第一次,那么我不会为可见性设置动画。这很有效,因为我不想看到我的表格单元格出现在网格中,然后让所有按钮都淡入 - 绑定上的点是当用户交互期间底层模型发生变化时淡出按钮... 这很好。
问题出现了,当我的手机被重新使用时#39;通过TableViewSource。绑定被重复使用,并且不再考虑第一次' - 所以按钮动画。当你在列表中上下滚动时,这会产生这样的效果,所有的按钮都会逐渐淡入'当他们滚动到视图中......你可以想象,它看起来很糟糕。
如何以干净的方式解决这个问题?
我考虑过在TableViewSource中放置一些代码,测试重用,然后在重用的单元格上,访问绑定集,并尝试重置'所有绑定...但是无法从MvxFluentBindingDescriptionSet定义访问绑定集合。
有什么想法吗?
由于
答案 0 :(得分:0)
好的 - 我拼凑了一个解决方案......
尽管如此,如果有人知道原生MVVMCross解决方案的方式,请随时提供更好的答案。
值得庆幸的是,MVVMCross在其生命周期结束时为MvxTableViewCell.DataContext指定了NULL - 因此我可以使用它来指示单元格绑定应该“重置”。我也无法通过使用静态属性来访问绑定集中的targetbindings列表(有点我知道,但是嘿,当你查看代码发生了什么时它很明显 - 这仍然是UI单元测试并不是什么大问题。)
这是一个想法(伪代码):
MyMvxConvertingTargetBinding.SetValueImpl:
if 'is_first_time' then
// don't animate the first-time binding of a view. Simple.
set view value, clear 'is_first_time' and return.
if 'ISRESETTING' then
// this is to ensure the View has the correct value,
// but is not animated when the table-view-cell is
// being removed from the table. It also resets the first-time state
// so that when a new DataContext is assigned, it will perform
// clean 'first-time' behavior.
reset 'is_first_time' to TRUE, set view value, and return
if is_first_time
then set view value and return
otherwise, animate setting of view value
MvxTableViewCell.DataContext.Set:
if current DataContext is not null and new DataContext is null:
// This allows the TargetBinding to capture the fact that
// the source data-model is being disconnected
static MyMvxConvertingTargetBinding.ISRESETTING = TRUE
Assign base.DataContext
finally static MyMvxConvertingTargetBinding.ISRESETTING = FALSE
最后,当您使用一个特殊的“动画绑定”时,想法将出现在任何MvxTableViewCell中,请确保覆盖DataContext并包装'base.set;在try / catch中切换'ISRESETTING',就像在伪代码中一样。这很有效。
这个实际修复的另一个问题是,重新使用的表视图单元仍然将子视图设置为“hiddden”状态,此时单元格被重新使用,因此重新设置为'可见'状态。这会导致相互冲突的动画,这可能会导致单元格出现在表格中,当它应该可见时,它的子视图会隐藏!
什么是好的,是一个允许MvxTargetBinding捕获与给定绑定有关的模型的DataContext中的更改的服务。那么我们就不需要这里使用的静态场方法了。