Force a specific Size Class on a view

autolayout, ios, nslayoutconstraint, objective-c, size-classes

Solution

The way this is meant to be accomplished is with trait collections on UIViewController, easily by calling `-setOverrideTraitCollection:forChildViewController:`.

However, as the API title indicates, a UIViewController can only have its traitCollection overriden by its parent. Presented View Controllers aren't children of their parent (the header file specifically notes presented view controllers aren't included in Child View Controllers) so you will have to add a "ToPresentViewController".

In this example, in IB there is `ToPresentViewController` scene that is only a container ViewController attached to its sides with constraints of 0, and the view controller that will be presented embedded.

@implementation ToPresentViewController


-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];

    if(thisDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad)
    {
        return;
    }

    for (UIViewController *controller in self.childViewControllers) { //Should be only one
        UITraitCollection *regularWidthTraits = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
        [self setOverrideTraitCollection:regularWidthTraits forChildViewController:controller];
    }

}

This will lock the size class to regular on iPad.

EDIT: The WWDC sample code here suggests indicates only the overridden traits need to be provided, which makes sense because in the original answer with a old+new merged collection it wasn't clear how it knew which to use.

Problem

I have a view that needs different constraints between the iPad & iPhone version. The login screen is presented as full screen on iPhone & in a page sheet on the iPad. Due to size the UITextFields are 40 pixels away from the right and left sides on the iPhone, but I want them to be 80 pixels on the iPad. I set this as a specific constraint for the Final Values Size Class (w Regular, h Regular). However because this view appears on a page sheet it doesn't use the Final Values Size Class. Ideally I would like to "force" the view to use a size class, rather than having an array of iPhone/iPad constraints and lots of constraint Outlets.

Original source

Related problems