Distinguish iPad orientation with size classes

北战南征 提交于 2020-01-11 09:17:17

问题


With iOS 8 Apple introduced size classes for handling layouts of an app. Instead of designing user interfaces dependent on device, screen size, and orientation, developers are encouraged to rather adapt their app's layout depending on the active size classes. That's a good move, I think.

However, when it comes to the iPad there seem to be no way to distinguish the different device orientations (which provide quite different screen space and handling in my opinion). From the Human Interface Guidelines:

What am I supposed to do now if I want to present a side menu only in landscape orientation because it provides more space, like a UISplitViewController?

Is the UISplitViewController another case where Apple doesn't eat it's own dog food and uses some other metrics like the device orientation or the actual screen width to determine the layout? Or is there another, official way to do that? Something I could do in Interface Builder alone without code?

(And no, I don't want to use UISplitViewController for several reasons.)


回答1:


This is how I resolved the issue you're having:

Use a different size class to add the constraints for portrait and landscape (which you seem to be doing) 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.

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;
    }
}


来源:https://stackoverflow.com/questions/31189792/distinguish-ipad-orientation-with-size-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!