第一个思路很好 ,
重点分享几个横屏和竖屏界面元素相对布局在方向上差别很大或完全不同的情形。
0x02 横屏和竖屏差别较大时的适配方案
0x02.0x01 使用xib,内置两个不同的View,方向旋转时切换
下面是一种业务场景,A,B,C,D四个View在横屏和竖屏状态下的布局分别如图-4和图-5所示。 该如何实现这种布局呢(要兼容iOS7,暂不考虑使用SizeClass)?
这种情形可以使用xib来布局,新建一个ViewController,添加两个与根View平行的View,其中一个称之为portraitView,负责竖屏布局;另一个称之为landscapeView,负责横屏布局,然后在ViewController的viewDidLayoutsubviews里根据屏幕方向来动态切换。废话不多说了,直接show code吧。
@property (strong, nonatomic) IBOutlet UIView *landscapeView;
@property (strong, nonatomic) IBOutlet UIView *portraitView;
@property (strong, nonatomic) UIView *currentView;
......
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self setupViewForOrientation];
}
- (void)setupViewForOrientation
{
UIInterfaceOrientation oritentation = [[UIApplication sharedApplication] statusBarOrientation];
[_currentView removeFromSuperview];
if (UIInterfaceOrientationIsPortrait(oritentation)) {
[self.view addSubview:_portraitView];
_currentView = _portraitView;
[_currentView setFrame:self.view.bounds];
} else if (UIInterfaceOrientationIsLandscape(oritentation)) {
[self.view addSubview:_landscapeView];
_currentView = _landscapeView;
[_currentView setFrame:self.view.bounds];
}
}
xib中view的结构如下图:
另外:storyboard上还不太清楚怎么添加多个平行的根view,请大神指教。
0x02.0x02 使用带有优先级的多约束,方向旋转时,动态更改约束的优先级
再来看下面图7和图8这个业务场景:横屏下A和B水平排列,竖屏下A和B垂直排列。同样,如果使用xib,添加两个不同的view,可以很快的完成需求。这里再提供一种思路,使用带有优先级的多个约束条件来实现,当屏幕方向旋转时,动态改变约束的优先级来达到目的。
在Autolayout中,添加的每个约束都有一个priority(优先级)的概念,默认状况下高优先级的会覆盖低优先级的约束,因此我们在布局时可以给元素添加多个约束条件(优先级不同),然后在屏幕方向旋转时,动态改变约束的优先级来实现横竖屏不同的界面布局。 show code time:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *colorViewHeightConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *colorViewBottomConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *colorViewWidthConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *colorViewTrailingConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *grayViewTopToColorViewConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *grayViewTopToSuperViewConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *grayViewLeadingToSuperViewConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *grayViewLeadingToColorViewConstraint;
......
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self setupViewForOrientation];
}
......
- (void)setupViewForOrientation
{
UIInterfaceOrientation oritentation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsPortrait(oritentation)) {
_colorViewHeightConstraint.priority = UILayoutPriorityDefaultHigh;
_colorViewBottomConstraint.priority = UILayoutPriorityDefaultLow;
_colorViewTrailingConstraint.priority = UILayoutPriorityDefaultHigh;
_colorViewWidthConstraint.priority = UILayoutPriorityDefaultLow;
_grayViewTopToColorViewConstraint.priority = UILayoutPriorityDefaultHigh;
_grayViewTopToSuperViewConstraint.priority = UILayoutPriorityDefaultLow;
_grayViewLeadingToSuperViewConstraint.priority = UILayoutPriorityDefaultHigh;
_grayViewLeadingToColorViewConstraint.priority = UILayoutPriorityDefaultLow;
} else if (UIInterfaceOrientationIsLandscape(oritentation)) {
_colorViewHeightConstraint.priority = UILayoutPriorityDefaultLow;
_colorViewBottomConstraint.priority = UILayoutPriorityDefaultHigh;
_colorViewTrailingConstraint.priority = UILayoutPriorityDefaultLow;
_colorViewWidthConstraint.priority = UILayoutPriorityDefaultHigh;
_grayViewTopToColorViewConstraint.priority = UILayoutPriorityDefaultLow;
_grayViewTopToSuperViewConstraint.priority = UILayoutPriorityDefaultHigh;
_grayViewLeadingToSuperViewConstraint.priority = UILayoutPriorityDefaultLow;
_grayViewLeadingToColorViewConstraint.priority = UILayoutPriorityDefaultHigh;
}
}
PS:总觉得这里要写的改变约束的代码有点啰嗦,不过确实是提供了另一种不同的思路。