1

I am creating a TableCell using Cirrious.FluentLayout in MVVMCross to add constraints.
I've added four images to the ContentView and have had to manually space them out (Horizontally) by calculating the margin in the constructor

var gap = (ContentView.Frame.Width - (imagesize * 3) - 40) /6;

Then I use the calculated gap for the constraints

        _signalStrength.ToRightOf(_batteryLevel, gap),
        _childLockImage.ToRightOf(_signalStrength, gap),

Currently this will work fine as the app only runs in Portrait mode, but I am concerned that if we enable landscape mode then this will not work.

Is there a better way to have these images pace evenly across the table cell?

Ashley Jackson
  • 183
  • 1
  • 1
  • 8

2 Answers2

2

I would advise you to use a UIStackView in horizontal mode with equal spacing distribution. UIStackView was added in iOS 9 and really helps with these cases and eliminate the need for a huge amount of constraints.

In your case, with 4 views, laid out horizontally with equal spacing, the code would look something like:

var views = new UIView[] { view1, view2, view3, view4 };
var stackView = new UIStackView(views)
{
    Axis = UILayoutConstraintAxis.Horizontal,
    Distribution = UIStackViewDistribution.EqualSpacing
};

Then you simply constrain your stackView instead and subviews will layout inside of it.

Cheesebaron
  • 24,131
  • 15
  • 66
  • 118
  • I have ported TZStackView to Xamarin, if you care about iOS 7 and 8 and can be found on NuGet. The API is similar with some minor changes to enums used for Axis, Distribution etc. due to them not being present on those older versions. – Cheesebaron Mar 02 '17 at 12:34
  • When I add code like you gave I get an error when adding it with fluent constraints: NSInternalInconsistencyException Reason: Impossible to set up layout with view hierarchy unprepared for constraint. What am I missing? – cfl Jun 19 '17 at 06:26
  • Solution: make sure you Add(stackView); before using it with constraints – cfl Jun 19 '17 at 06:34
  • @cfl like with any other view you want to add constraints for :) – Cheesebaron Jun 19 '17 at 08:40
  • :) true - confusion due to trying to add constraints on the individual views themselves, e.g. add textview onto view1 using it's own fluent constraint. – cfl Jun 19 '17 at 10:56
1

UIStackView answer by @Cheesebaron is a very good way to go.

However, if you care about iOS 7-8 (UIStackView works on 9+), then here's what you can do:

view.AddConstraints(
    i1.WithSameCenterX(view).WithMultiplier(1 / 4f),
    i2.WithSameCenterX(view).WithMultiplier(3 / 4f),
    i3.WithSameCenterX(view).WithMultiplier(5 / 4f),
    v4.WithSameCenterX(view).WithMultiplier(7 / 4f)
);

i1-i3 are images of same size and v4 is some other view of different size. No manual calculation required.

Works in portrait mode: portrait

and landscape:

landscape

The idea is explained in this brilliant answer: https://stackoverflow.com/a/30249550/883738

If your views will be of different size, this might be not exactly what you want:

not exactly what you need

Community
  • 1
  • 1
Alex Sorokoletov
  • 3,102
  • 2
  • 30
  • 52
  • 1
    You can use TZStackView on iOS versions prior to 9. Full disclaimer, I made a port for Xamarin.iOS which is on NuGet. – Cheesebaron Jun 19 '17 at 08:40