UITraitCollection Class for Updating the Size Clas

2019-08-29 07:09发布

Shall i use UITraitCollection Class for Updating the Size Class constraints? Is this Best Practice to update the Constraints?

I have gone through the UITraitCollection, but don't know how to differentiate portrait and Landscape?

1条回答
迷人小祖宗
2楼-- · 2019-08-29 07:39

It sounds like you want a different layout based on iPad orientation. If adjusting constraint values is all you need to do, you can check the UITraitCollection's horizontalSizeClass and verticalSizeClass properties. The size class properties values can be found at the Apple documentation for UIUserInterfaceSizeClass. I can't vouch for this being best practice, but I don't see anything wrong with it. An alternative to checking the UITraitCollection would be to check UIInterfaceOrientationIsPortrait as seen below in the code snippet.

A more complex scenario requires the use of completely different constraints for landscape vs portrait. You could handle adding those constraints programmatically, or you can use a different size class to add the constraints and then create an IBOutletCollection for the constraints for each size class that are based on the orientation.

For example, I used wAnyhRegular to setup my portrait iPad layout and then used wRegularhAny to setup my landscape iPad layout. (Although you may want to use wRegular/hRegular as one of your orientation layouts since iPad registers as wRegular/hRegular when you check the UITraitCollection. Hopefully the code below demonstrates how I went about it:

@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *iPadPortraitConstraints;
@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *iPadLandscapeConstraints;

My portrait constraints can be seen below. My landscape has 3 constraints as well. Portrait Constraints

I then apply the constraints as noted below (not shown, viewDidLoad executes _needsiPadConstraintsApplied = YES;):

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    [self applyiPadConstraints];
}

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    //  Size Classes does not support differentiating between iPad Portrait & Landscape.
    //  Signal that the iPad rotated so we can manually change the constraints.
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        _needsiPadConstraintsApplied = YES;
    }
}
- (void)applyiPadConstraints {

    if (_needsiPadConstraintsApplied) {

        if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
            [NSLayoutConstraint deactivateConstraints:self.iPadLandscapeConstraints];
            [NSLayoutConstraint activateConstraints:self.iPadPortraitConstraints];

        } else {
            [NSLayoutConstraint deactivateConstraints:self.iPadPortraitConstraints];
            [NSLayoutConstraint activateConstraints:self.iPadLandscapeConstraints];
        }

        _needsiPadConstraintsApplied = NO;
    }
}

And finally, you may find this exploration of size classes helpful.

查看更多
登录 后发表回答