0

I try to implement the following structure of views in my Xamarin.iOS application. I'm using FluentLayout and MvvmCross 6.0.1.

View (controller)
 - UIScrollView
   - UIView
      - UIView,
      - UIView/UILabel etc.
      - UIView/UILabel etc.
      - ...

I'd like the view to be scrollable, but unfortunately it is possible only the second time I navigate to this view. In other words you have to navigate back and navigate to the view again to be able to scroll this view.

The controller is inside the MvxBaseViewController i.e. the structure of controllers is like this:

- DashBoard (MvxTabBarViewController, WrapInNavigationController=true)
  - Tab1 (MvxBaseViewController)
  - Tab2 (MvxBaseViewController)
  - Tab3 (MvxBaseViewController)
    - The problematic view (MvxBaseViewController)

I was following this guide while setting up the constraints which are as follows:

var innerView = new UIView();
innerView.AddSubview(view1);
innerView.AddSubview(view2);
innerView.AddSubview(view3);

innerView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
innerView.AddConstraints(
    view1.AtTopOf(innerView).Plus(21.0f),
    view1.WithSameCenterX(innerView),
    view1.WithSameWidth(innerView).WithMultiplier(0.8f),
    view1.Height().EqualTo(44f),
    view2.Below(view1).Plus(10.0f),
    view2.WithSameCenterX(innerView),
    view2.WithSameWidth(innerView).WithMultiplier(0.9f),
    view2.Height().EqualTo(16.0f),
    view3.Below(view2).Plus(21.0f),
    view3.WithSameCenterX(innerView),
    view3.WithSameWidth(innerView).WithMultiplier(0.9f),
    view3.Height().EqualTo(40.0f),
);

var scrollView = new UIScrollView();
scrollView.ShowsHorizontalScrollIndicator = false;
scrollView.AddSubview(innerView);

scrollView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
scrollView.AddConstraints(
    innerView.AtTopOf(scrollView, 0),
    innerView.AtBottomOf(scrollView, 0),
    innerView.AtLeadingOf(scrollView, 0),
    innerView.AtTrailingOf(scrollView, 0)
);

//scrollView.DirectionalLockEnabled = true;
View.AddSubview(scrollView);

View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
View.AddConstraints(
    //scrollView.WithSameWidth(View),
    //scrollView.WithSameHeight(View),
    innerView.WithSameWidth(View),
    innerView.WithSameHeight(View).SetPriority(250),
    scrollView.AtTopOf(View, 0),
    scrollView.AtBottomOf(View, 0),
    scrollView.AtLeadingOf(View, 0),
    scrollView.AtTrailingOf(View, 0)
);

I suspect that the problem is related to the constraints but I wasn't able to figure out what is wrong. Do you have any ideas how to solve this?

Dominik Roszkowski
  • 2,715
  • 1
  • 19
  • 46
  • Where are you calling this code from. If possible, paste the problematic view and view controller's full code, maybe on an open git repo, if its too large to add to the question – Swapnil Luktuke Sep 28 '18 at 10:47
  • Where you call this code from is most likely the problem. I would assume that it needs to be inside ViewDidLoad or ViewWillAppear. If I had to guess, you are probably calling it from your constructor right now. – DavidShepard Sep 28 '18 at 18:58
  • @SwapnilLuktuke layout was done just after ViewDidLoad – Dominik Roszkowski Sep 30 '18 at 16:33
  • @DavidShepard yes, the layout was prepared in ViewDidLoad(). I had to increase the ContentSize of scrollView manually in ViewDidAppear() – Dominik Roszkowski Sep 30 '18 at 16:34

1 Answers1

0

So I spent some time on the topic and couldn't find a proper way to constraint my views. I tried to implement this layout in xib but reimplementing the autogenerated constraints in code didn't help.

Finally I solved it by removing the innerView and placing everything inside scrollView. Then in ViewDidAppear() I increased the ContentSize of the scrollView in vertical direction.

scrollView = new UIScrollView();

scrollView.AddSubviews(view1,
                       view2,
                       view3);
scrollView.ShowsHorizontalScrollIndicator = false;
scrollView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

scrollView.AddConstraints(
    view1.AtTopOf(scrollView).Plus(21.0f),
    view1.WithSameCenterX(scrollView),
    view1.WithSameWidth(scrollView).WithMultiplier(0.8f),
    view1.Height().EqualTo(44f),

    view2.Below(view1).Plus(10.0f),
    view2.WithSameCenterX(scrollView),
    view2.WithSameWidth(scrollView).WithMultiplier(0.9f),
    view2.Height().EqualTo(16.0f),

    view3.Below(view2).Plus(21.0f),
    view3.WithSameCenterX(scrollView),
    view3.WithSameWidth(scrollView).WithMultiplier(0.9f),
    view3.Height().EqualTo(40.0f)
);

View.AddSubview(scrollView);
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

View.AddConstraints(
    scrollView.AtTopOf(View, 0),
    scrollView.AtBottomOf(View, 0),
    scrollView.AtLeadingOf(View, 0),
    scrollView.AtTrailingOf(View, 0),
    scrollView.WithSameCenterX(View),
    scrollView.WithSameCenterY(View)
);

And in ViewDidAppear:

scrollView.ContentSize = new CGSize(View.Bounds.Width, scrollView.Bounds.Height + 300);
Dominik Roszkowski
  • 2,715
  • 1
  • 19
  • 46