使用autolayout配置UIScrollView内容,使用键盘插入和旋转到横向

时间:2013-10-30 19:15:25

标签: ios uiscrollview autolayout landscape

我正在使用自动布局(iOS 6,7)中的滚动视图进行一段时间的战斗,而且它正在变得令人沮丧。

考虑一个简单的报名表

我想要可滚动,并且应该在横向上调整大小:

portrait

视图层次结构为:

view hierarchy

我需要配置适当的约束,以便

  • 当键盘出现并消失时,滚动区域会正确更新
  • 当设备旋转到横向并回到纵向时,
  • 内容会调整大小
  • 滚动区域适当地更新了横向和纵向

这可以在没有代码的情况下完成吗?

取而代之的是

键盘出现时滚动尺寸错误

wrong scroll size

内容未在横向

中调整大小

no resize in landscape

要使用的源代码:

source code

4 个答案:

答案 0 :(得分:9)

看哪!经过2天的搜索,我相信我可能会有一个答案。诚然,没有代码就无法完成。

首先从contentView到Scroll视图创建常用的top,bottom,leading和trailing约束。 但是使用前导和尾随,勾选“占位符 - 在构建时删除”选项。

然后在viewDidLoad方法中添加以下内容:

NSLayoutConstraint *leftConstraint =[NSLayoutConstraint
                                     constraintWithItem:self.contentView
                                     attribute:NSLayoutAttributeLeading
                                     relatedBy:0
                                     toItem:self.view
                                     attribute:NSLayoutAttributeLeft
                                     multiplier:1.0
                                     constant:0];
[self.view addConstraint:leftConstraint];

NSLayoutConstraint *rightConstraint =[NSLayoutConstraint
                                     constraintWithItem:self.contentView
                                     attribute:NSLayoutAttributeTrailing
                                     relatedBy:0
                                     toItem:self.view
                                     attribute:NSLayoutAttributeRight
                                     multiplier:1.0
                                     constant:0];
[self.view addConstraint:rightConstraint];

这会动态地将contentView中的前导和尾随约束添加到控制器的主视图中(即滚动视图之外)。

然后,当您旋转设备时,输入字段会被适当拉伸。 这解决了你的旋转问题,关于键盘出现在SO上的其他答案,但基本上在viewDidLoad里面:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardDidHideNotification object:nil];

然后添加以下两种方法:

- (void) keyboardWasShown:(NSNotification *)notification
{
  NSDictionary *info = [notification userInfo];
  CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
  UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0);
  self.scrollView.contentInset = contentInsets;
  self.scrollView.scrollIndicatorInsets = contentInsets;
}

- (void) keyboardWillBeHidden:(NSNotification *)notification
{
  UIEdgeInsets contentInsets = UIEdgeInsetsZero;
  self.scrollView.contentInset = contentInsets;
  self.scrollView.scrollIndicatorInsets = contentInsets;
}

答案 1 :(得分:4)

你的方法是可行的,值得修复,但如果你想要一种替代方法,那么它就是:

而不是普通的UIScrollView,而是使用带有静态行的UITableView。

在IB中,设计一个自定义静态表格单元格,其中包含UITextField作为子视图。在布置了自定义静态表格单元格后,将其复制并粘贴到表格视图中,直到您有7个相同的自定义静态表格单元格。然后将插座连接到每个文本字段。

创建另一个将UIButton作为子视图的自定义静态表格单元格。将插座连接到按钮。

带有静态单元格的表格视图不需要任何表格视图委托或数据源方法。

使用表格视图而不是普通卷轴视图的好处是具有第一响应者状态的文本字段在出现时会自动滚动到键盘上方。另一个好处是您不必处理滚动视图的内容视图以及其维度如何响应旋转。

如果为场景使用表视图控制器,则表视图的默认约束将适当地处理旋转。您需要处理的唯一限制是布置表格单元子视图的那些。

但是,如果您要坚持使用普通卷轴视图和自动布局,您可能需要查看Apple的技术说明(如果您还没有):https://developer.apple.com/library/ios/technotes/tn2154/_index.html#//apple_ref/doc/uid/DTS40013309

答案 2 :(得分:1)

我认为可以在不编写代码且仅使用IB的情况下尊重您的要求。

您只需将约束直接从contentView添加到viewController的self.view。

要绕过IB的限制以仅向superview添加约束(在本例中为scrollView),您只需按Ctrl键并将contentView拖动到self.view。

像这样:

http://i.stack.imgur.com/qFNKy.png

答案 3 :(得分:0)

使用AutoLayout将UITextField放在底部带有UIButton的UIScrollView中

Video