当方向改变时重新定位控制
我知道Auto Layout可以用来在方向改变时使尺寸和位置保持一致。 当方向改变时,是否可以完全改变布局?
例如,请在纵向模式下查看简单login屏幕的下面的线框。
现在,如果我旋转设备,我想完全重新定位控件。
这种事情可以通过使用自动布局来完成吗? 如果不是,我该怎么办呢?
谢谢。
在你的情况下,它可以通过两种方法来实现,而不是重新组织每个组件,你可以将控件分组如下。
-
父视图 – >用户信息视图 – >所有用户信息控件..通过这样做,你将不得不重新构build用户信息视图不是所有的控件..
然后只有徽标和公司名称左侧重新构build..总共3个控件重构,如果你分组你的控制..
-
为纵向创build两个视图,为横向模式创build两个视图,并在旋转中添加和移除。这是最快的方法,因为您不必通过繁琐的代码重新调整帧。
希望以上帮助。
你不能设置不同的帧: –
-(void)setFramesForPotrait { // set frames here } -(void)setFramesForLandscaeMode { // set frames here } -(bool)shouldAutorotate..... { return Yes } -()willAutoRotate...... { if(orientation = uiinterfaceOrientationPotrait) { [self setFramesForPotrait]; } else { [self setFramesForLandscape]; }
我有同样的问题,这是我迄今为止发现的。 我正在使用的方法是针对不同的屏幕大小或方向有两组(可能多个)约束。 所以我只是devise肖像,并连接到IBOutletCollection的特定肖像的所有约束: 然后将InterfaceBuilder中的VC方向切换到横向,并为此方向添加所需的约束,并连接到相应的sockets:
然后在代码中,我需要删除或添加约束:
- (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [self updateViewConstraints]; } - (void)updateViewConstraints { [super updateViewConstraints]; if (self.view.frame.size.width >= kSize * 2 + kPadding * 3) { [self.view removeConstraints:self.constraintsForPortrait]; [self.view addConstraints:self.constraintsForLandscape]; } else { [self.view removeConstraints:self.constraintsForLandscape]; [self.view addConstraints:self.constraintsForPortrait]; } }
您可以使用此代码实现类似的结果,根据方向而不是帧大小添加/删除约束:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; [self updateViewConstraints]; }
但是请记住,苹果传闻将会发布具有不同屏幕长宽比的设备,并且会放弃UIInterfaceOrientation和旋转事件,这可能是值得提前准备的。 将看看未来会带来什么。
这种方法的缺点是,Xcode会抱怨devise模糊,实际上,因为Xcode不知道我们会在运行时消除模糊性。 为了解决这个问题,你可以把约束的优先级设置为对于在这个特定时刻你没有devise的所有其他方向是可选的(例如,如果你正在devise肖像,那么可选的景观约束)。
使用自动布局时,您可以重写updateViewConstraints以修改方向更改的布局:
- (void)updateViewConstraints{ [super updateViewConstraints]; //portrait if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){ } //landscape else{ // } }
这可以通过布局约束来完成,就像下面的例子一样。 这并不奏效,因为你的素描不起作用 – 与你真正的风景相比,你的风景视图太长了。 你将不得不缩短login文本字段的一切适合,但这应该给你一个想法是如何完成的。 buttonWidth约束显示了如何在视图的宽度和button的宽度之间具有负相关性 – 也就是说,横向上的button的宽度将小于纵向中的宽度。 我有几个IBOutlets约束,我在代码中引用。 如果你有兴趣的话,我可以为你描述一下,但是我现在就把它扔出去:
@implementation ViewController { IBOutlet NSLayoutConstraint *buttonWidth; IBOutlet NSLayoutConstraint *logoTop; IBOutlet NSLayoutConstraint *logoAlignToLabel; IBOutlet NSLayoutConstraint *logoSpaceToLabel; IBOutlet NSLayoutConstraint *coNameToButtonAlignment; IBOutlet UIButton *b; IBOutlet UIImageView *logo; IBOutlet UILabel *coName; NSLayoutConstraint *con2; NSArray *cons1; } - (void)viewDidLoad { [super viewDidLoad]; [b removeConstraint:buttonWidth]; buttonWidth = [NSLayoutConstraint constraintWithItem:b attribute:NSLayoutAttributeWidth relatedBy:0 toItem:self.view attribute:NSLayoutAttributeWidth multiplier:-.2193 constant:350]; [self.view addConstraint:buttonWidth]; [self.view layoutSubviews]; } - (void)updateViewConstraints{ [super updateViewConstraints]; if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){ if (con2 != nil) { [self.view removeConstraints:cons1]; [self.view removeConstraint:con2]; [self.view addConstraints:@[logoAlignToLabel,logoSpaceToLabel,logoTop,coNameToButtonAlignment]]; } }else{ NSLog(@"Landscape"); [self.view removeConstraints:@[logoAlignToLabel,logoSpaceToLabel,logoTop,coNameToButtonAlignment]]; cons1 = [NSLayoutConstraint constraintsWithVisualFormat:@"|-8-[logo]-4-[coName]" options:NSLayoutFormatAlignAllCenterY metrics:0 views:@{@"logo":logo, @"coName":coName}]; con2 = [NSLayoutConstraint constraintWithItem:logo attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]; [self.view addConstraints:cons1]; [self.view addConstraint:con2]; } }
在旋转徽标和公司名称标签已被删除的约束,新的到位。 我在viewDidLoad中添加的button的新约束自动处理旋转,所以在旋转过程中我不必调整它。