9

一段时间以来,我一直在与自动布局(iOS 6,7)中的滚动视图作斗争,而且越来越令人沮丧。

考虑一个简单的输入表单

我希望是可滚动的,并且应该在横向调整大小:

肖像

视图层次结构是:

视图层次结构

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

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

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

我得到的是

出现键盘时滚动大小错误

错误的滚动大小

内容未横向调整大小

横向没有调整大小

要玩的源代码:

源代码

4

4 回答 4

9

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

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

然后在您的 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;
}
于 2013-12-18T16:07:53.327 回答
4

您的方法是可行的并且值得修复,但如果您想要另一种方法,这里是:

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

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

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

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

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

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

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

于 2013-10-30T22:23:18.670 回答
1

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

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

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

像这样:

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

于 2014-03-28T14:51:56.220 回答
0

使用 AutoLayout 将 UITextFields 放入底部带有 UIButton 的 UIScrollView

视频

于 2015-06-12T11:46:49.543 回答