0

In most cases the layout of data on the screen won't really depend on the data itself, and it's straight forward to manage simple settings like visibility settings with mvvmcross by binding to isHidden. For more advanced screen related aspects, it's possible to subclass the view, and make view adjustments in the setter. Example of this is in N=33 - "Animating Mvvm Text in iOS, Android and Windows - N+1 Days of Mvvmcross". Specifically here is what I'm talking about.

But what if I have a situation where I want to have the positioning of the element that binds to the data on the screen depend on the data itself, and to make things worse -- what if the positioning rules affect other elements on the screen as well?

An example of this is: centering up to 5 buttons on a screen, 10 pixels apart. Each button should be excluded should some source data be null -- so the rest of the buttons layout on the screen must change depending on the data. At all times we want the buttons 10 pixels apart, regardless how many buttons were skipped.

For iOS autolayout can accommodate this. But let's say I'm not using autolayout right now, and even though I will likely adopt its use, what would an alternative be where I do the layout manually in code? There might be cases where the layout rules would be non-linear or too complex for autolayout to be able to configure the view for me.

What I've done (for now) is to subclass the view element(s) in question, and in the setter, run a relayout method on the parent view that applies the rules I need for all child elements. The lame part about this approach is that I run relayout once for each such element, when I really only needed that code to run one time (at least for the initial values). Thereafter, should any data change that was bound this way, it is appropriate to relayout the entire view, but not when we first initialize the screen and ALL values change at once.

So at minimum, it'd be great to suppress the initial flurry of relayout calls (one for each screen element that influences other elements during the initial data rolls in).

Does anyone have thoughts on this?

Community
  • 1
  • 1
Bernie Habermeier
  • 2,580
  • 2
  • 22
  • 20
  • 1
    If you are doing your own layout, then I recommend you try using `setNeedsLayout` and `layoutSubviews` - these are standard iOS `UIKit` mechanisms and are already optimised to ensure that excess calls aren't made. – Stuart Aug 25 '14 at 08:38
  • You are so right. Thanks for that suggestion. Works beautifully. – Bernie Habermeier Aug 25 '14 at 19:38

1 Answers1

0

I would use the Messenger plugin to communicate relayout requests from the ViewModel to the View.

Publish the RelayoutMessage after initialization. Then publish again whenever the data changes.

By using messages you're still keeping the View and ViewModel separate.

Kiliman
  • 18,460
  • 3
  • 39
  • 38
  • I'll check out the Messenger plugin. I've adopted Stuart's suggestion above with using the SetNeedsLayout / LayoutSubviews, and that works well. Thanks for the suggestion. – Bernie Habermeier Aug 25 '14 at 19:39