Search code examples
c#xamarinautolayoutconstraintssize-classes

How to use code behind to set different constraints for Auto Layout using Xamarin iOS


Using Xamarin iOS to build my view with C# code behind (without a designer), how can I create different set of constraints for different size classes?

For now, all I managed is to create constraints using code only and it works great but it's the same set of constraints for all sizes / orientations.

This code creates two custom views and set them to fill the screen from left to right and locate them one under the other. This is great for iPhone 6+ in portrait mode but in landscape mode I want it to hide the second view (SomePanel) and stretch the first view (MainPanel) all over the screen.

 partial class SomeView : MvxViewController
{
    CustomView MainPanel;
    CustomView SomePanel;

    public SomeView (IntPtr handle) : base (handle)
    {
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        /// First Panel
        MainPanel = CustomView.Create ();
        View.AddSubview (MainPanel);
        MainPanel.TranslatesAutoresizingMaskIntoConstraints = false;


        /// Second Panel
        SomePanel = CustomView.Create ();
        View.AddSubview (SomePanel);
        SomePanel.TranslatesAutoresizingMaskIntoConstraints = false;



        /// <summary>
        /// First set of constraints - two panels one under the other
        /// </summary>
        View.AddConstraint (NSLayoutConstraint.Create (MainPanel, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, View, NSLayoutAttribute.CenterX, 1f, 0f));
        View.AddConstraint (NSLayoutConstraint.Create (MainPanel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, View, NSLayoutAttribute.Top, 1f, 50f));
        View.AddConstraint (NSLayoutConstraint.Create (MainPanel, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1f, 60f));
        View.AddConstraint (NSLayoutConstraint.Create (MainPanel, NSLayoutAttribute.Width, NSLayoutRelation.Equal, 1f, View.Bounds.Width - 40));

        View.AddConstraint (NSLayoutConstraint.Create (SomePanel, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, View, NSLayoutAttribute.CenterX, 1f, 0f));
        View.AddConstraint (NSLayoutConstraint.Create (SomePanel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, MainPanel, NSLayoutAttribute.Bottom, 1f, 20f));
        View.AddConstraint (NSLayoutConstraint.Create (SomePanel, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1f, 60f));
        View.AddConstraint (NSLayoutConstraint.Create (SomePanel, NSLayoutAttribute.Width, NSLayoutRelation.Equal, 1f, View.Bounds.Width - 40));

    }

}

I know it is easy to do using the designer, set your constraints, change the size classes using the designer and edit the constraints, again from the designer.

But in my case I want to do it using code and i can't really find a guide or examples of how to set different set of constraints for different size classes / different orientations.

Any help is appreciated.


Solution

  • You could override WillAnimateRotation to detect orientation changed, just update View Constraints here

    public override void WillAnimateRotation (UIInterfaceOrientation toInterfaceOrientation, double duration)
    {
        base.WillAnimateRotation (toInterfaceOrientation, duration);
        //Update view constraints...
    }
    

    Another option is managing all view on UpdateViewConstraints, normally this is fired when ViewController is loaded, but we could fire it again every time orientation is changed but update WillAnimateRotation

        public override void WillAnimateRotation (UIInterfaceOrientation toInterfaceOrientation, double duration)
        {
            base.WillAnimateRotation (toInterfaceOrientation, duration);
            View.SetNeedsUpdateConstraints ();
        }
    
        public override void UpdateViewConstraints ()
        {
            base.UpdateViewConstraints ();
            var currentOrientation = InterfaceOrientation;
            //Update view constraints with current orientation
        }