【问题标题】:Configure UIScrollView content with autolayout, insets for keyboard, and rotation to landscape使用自动布局、键盘插入和旋转到横向配置 UIScrollView 内容
【发布时间】:2013-11-10 14:16:46
【问题描述】:

我在使用自动布局 (iOS 6,7) 中的滚动视图已经有一段时间了,而且越来越令人沮丧。

考虑一个简单的输入表单

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

视图层次结构是:

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

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

这可以不用代码来完成吗?

我得到了什么

出现键盘时滚动大小错误

内容未横向调整大小

使用的源代码:

source code

【问题讨论】:

  • 您对重构视图层次结构的想法持开放态度吗?
  • 当然。只要符合要求。
  • @paiv 你应该看到这个视频,那里显示了一个与你的案例非常相似的案例:youtube.com/watch?v=PgeNPRBrB18
  • 他专注于 struts-and-strings 布局,我无法将其应用于我的案例。在最后一分钟,他谈到了自动布局的不同之处,但这无济于事。我希望他有源代码可以下载。是否还有带有自动布局的 contentView?如果视图内容较少并且不应该纵向滚动,而是在键盘出现时滚动,或者旋转到横向怎么办?我什至无法在旋转时调整字段大小。
  • 您可以尝试保留对高度和宽度约束的引用,并在设备旋转时更新它们的常量。

标签: ios uiscrollview autolayout landscape


【解决方案1】:

看!经过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];

然后添加这2个方法:

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

【讨论】:

  • 占位符的有趣发现,很高兴知道。谢谢你。我目前正在与 contentView 和滚动视图底部之间的底部空间作斗争。在我的示例中,纵向视图不应滚动,但横向应垂直滚动。
  • 好的,这对我有帮助:stackoverflow.com/a/17220494/652122 我需要将 contentView 和 scrollView 之间的底部约束设置为零。
  • 感谢上帝的回答!但为什么有必要?为什么 UIScrollView 正确地从定义其子视图高度的约束中推断出它的 contentSize.height,而不是 contentSize.width?
  • 这个解决方案有效,但不知何故,只有屏幕的左侧部分,可能对应于纵向模式的宽度,处理滚动,屏幕的右侧部分是“死的”。以前有人经历过吗?如果是,如何解决?
  • 作为添加约束以将 contentView 的左/右绑定到外部视图的替代方法,您可以在 Interface Builder 中将 contentView 和主视图的宽度设置为相等。见:natashatherobot.com/ios-autolayout-scrollview
【解决方案2】:

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

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

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

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

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

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

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

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

【讨论】:

  • 我已阅读该技术说明,但仍无法理解我的情况。我现在会坚持使用表格视图控制器,因为它们为我做这些事情,但真的很想了解它们在这方面的内部结构。滚动视图更加通用,我想使用它们,而不是表格。
【解决方案3】:

我认为无需编写代码而仅使用 IB 即可满足您的要求。

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

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

像这样:

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

【讨论】:

    【解决方案4】:

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

    Video

    【讨论】:

      猜你喜欢
      • 2014-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-27
      相关资源
      最近更新 更多