如何在Interface Builder中使用UIScrollView?


95

虽然我UIScrollView过去通过编程方式成功地使用它,但我仍然无法通过在Interface Builder中进行专门设置​​来使其正常工作。

我的iPhone应用程序中有一个简单的“关于”页面。它有一个UITextView,一些图标,以及指向我其他应用程序的链接。我已将所有这些视图添加到我的视图中UIScrollView,并进行了排列,以使其总大小>480。启动应用程序时,scrollview仅显示适合屏幕显示的内容,而不会滚动。

是否可以完全通过IB来做到这一点,还是必须通过代码来操作contentSize?

Answers:


130

您忘记设置UIScrollView的contentSize属性。奇怪的是,您无法在Interface Builder中执行此操作。您将必须从管理此滚动视图的视图控制器中执行此操作。


42
哇,有点让IB变得毫无意义...做到了,谢谢。
乔治·阿姆霍尔德

20
您可以创建UIScrollvView的子类,以检查在(0,0)处是否只有一个子视图,然后根据该子视图自动设置contentSize。
Stefan Arentz,2009年

1
这是我一段时间以来收到的最好的建议。我不知道为什么我的滚动视图不起作用,并且在其他任何地方都找不到关于contentSize的信息。谢谢。
Drew C

46
我试图弄清楚如何在Interface Builder中设置contentSize,并找到了这个讨论。至少对我来说,在Xcode 4.5中,我可以使用“用户定义的运行时属性”通过添加名为contentSizetype 的条目Size并设置所需的值来进行设置。
nlogax 2012年

5
对于iOS为什么不仅仅根据其子视图的尺寸自动将contentSize滚动视图的设置(至少作为默认行为),我仍然感到困惑。
aroth

113

Boby_Wan的答案引起了我的思考,我找到了以下解决方案来从Interface Builder配置UIScrollView的contentSize:

  1. UIScrollView在情节提要场景中选择
  2. 转到身份检查器,创建一个新的用户定义的运行时属性(单击+按钮)
  3. 将属性“ 密钥路径”更改为contentSize
  4. 将属性类型更改为Size
  5. 现在将“ ”设置为{ 所需的内容宽度所需的内容高度 }

例如,将值设置为{320,920}将使用户向下滚动iPhone上的整个额外屏幕。

(我使用的是xcode 4.3.3,该项目的iOS部署目标为5.1)

第一次执行此操作时,收到以下错误:

非法配置:
     大小类型的用户定义的运行时属性,具有4.3
     MainStoryboard.storyboard 之前的Xcode版本

如果您也收到此错误,则很容易解决:在“ 项目浏览器”中选择“情节提要” ,然后打开“ 文件”检查器。查找/展开“ 界面生成器文档”部分,然后有一个“ 开发”下拉列表。确保将其设置为Xcode 4.3


7
很棒的发现!PS:我很惊讶这是Apple可以做的最好的事情。我猜这表明,即使Apple员工也从未使用过自己的工具(界面生成器):)。
2012年

太棒了,这在Xcode 4.4中对我来说才有效。但是现在如何在IB中无法“看到”的滚动视图部分放置按钮?
罗伯特·阿特金斯

1
我刚刚解决了这个问题–您必须在指针仍位于“屏幕”内部时释放拖动,否则它将重新回到您开始时的位置。真痛苦
罗伯特·阿特金斯

我以这种方式尝试过,但出现错误"this class is not key value coding-compliant for the key keyPath",请您能帮助我我在做什么错?请注意,我使用xamarin-ios-c#
SoftSan 2014年


18

您可以仅使用Interface Builder进行操作,转到Identity Inspector(第三个检查器选项卡),然后使用以下命令添加新的User Defined Runtime属性:

  • 关键路径: contentSize
  • 类型: 大小
  • 值: {宽度,高度}

14

现在有一种方法可以使 UIScrollView无需离开Storyboard即可滚动:

  1. UIScrollView在情节提要中选择,转到尺寸检查器和更换底部的值(或者任何你需要改变其他值)内容插图部分内容区域的高度。
  2. 现在转到身份检查器并创建一个新的用户定义的运行时属性(通过单击+按钮)并将其命名contentSize。没关系填写类型(甚至可以保留其默认值)。

UIScrollView尽管我不知道为什么第二步是必要的(我偶然发现),但这将使工作正常进行。:(


将Bottom值更改为什么?
zakdances 2012年

将其更改为内容区域的高度。它似乎有效,并且可以覆盖您为用户定义的“ contentSize”属性提供的值。
里德·埃利斯

是的,Reid,您是对的:您应该将Bottom值更改为内容区域的高度。我已经编辑了原始帖子以反映这一点。谢谢!
RoberRM

4

我过去使用的一种方法是在界面生成器中将滚动视图拖出包含视图的位置,并将其实际大小设置为想要的contentSize。

接口构建器在本质上不是显而易见的是,您可以具有存储在笔尖中的未关联视图,但是这些视图不是笔尖主要用于的主视图的一部分。

在希望滚动视图存在的视图中,放置一个简单的UIView,用作占位符。(这仅仅是为了使您可以直观地设计它的位置。如果您只是使用整个视图,则可以跳过此步骤,并使用此答案末尾提供的第二个代码段)。

然后,您可以使用控件填充滚动视图,以可视方式将其布局为您希望的样子。在视图控制器中同时提供占位符和scrollview属性,以便您在运行时对其进行访问。

在运行时,在-(void)viewDidLoad中

scrollView.contentSize = scrollView.frame.size;
scrollView.frame = placeholder.frame;
[placeholder.superview addSubView:scrollView];
[placeholder removeFromSuperview];

或者(如果您不使用占位符):

CGRect f = self.view.frame;
scrollView.contentSize = f.size;
f.origin.x = 0;
f.origin.y = 0;
scrollView.frame = f;
[self.view addSubView:scrollView];

最后,如果您在界面构建器中“丢失”了滚动视图(可以将其关闭以使其从设计网格中消失),请不要惊慌。只需在设计网格左侧的对象列表中单击它即可。


1
谢谢-效果很好。还需要在YourViewController.h中为占位符和滚动视图声明IBOutlets,然后在Interface Builder中将它们连接起来。最后,第三行的xCode并不喜欢dot.notation,因此使用了普通的消息发送语法-一切都很好!
jiy 2012年

别担心。在发布代码段时总是存在一些危险,即某些人无法使用它们来获得概念,而不是期望“精确的”代码在每种情况下都能正常工作。
不同步的2012年

这是我实际使用的方法。我什至不需要调整该程序的大小。我认为这就是要完成的方式。这是一个真实的答案。
user4951 2012年

将其绘制到外部之后,我将其移至超级视图。多田
user4951 2012年

实际上,我实际上是开始使用场景的外部视图设计暂存器的,这样在某些情况下(甚至与此无关),生活变得更加轻松。感谢您的回答。
本杰明

4

在使用自动布局的Xcode 4.5中,我的大小检查器中没有“内容插入”部分。因此,我必须将其添加到“用户定义的运行时属性”下,然后才能正常工作。

在“用户定义的运行时属性”中添加的是keyPath == contentInset,其类型为“ Rect”(UIEdgeInsets,其输入与Rect相同),并定义为{top,left},{bottom,right}。contentSize仅定义滚动视图窗口的区域。contentInset定义可滚动区域。

我希望这对处于相同情况的人有所帮助。


对于UITextView,请使用“ textContainerInset” keyPath
Dima Deplov'2

4

上面的许多答案都是误导或过时的。截至2017年(可能更早),界面生成器确实支持具有自动调整大小的内容的滚动视图。诀窍在于,XCode为滚动视图与其内部内容之间的约束提供了特殊的非标准含义。这些“向内”约束实际上不会像您期望的那样实际影响内容的大小。

这意味着您可以例如将滚动视图固定在主视图的底部,且边距为零,也可以将滚动视图的内容固定在滚动视图的底部,边距为零,但是实际上并不会因此而被拉伸。取而代之的是,内容将获得其自己确定的大小(更多信息,请参见下文),这也将是滚动视图内可滚动区域的大小。

这样想吧-将约束绑定到滚动视图有一个不对称性:从滚动视图到“外部”(父)世界的约束通常确定滚动视图的大小和位置。但是滚动视图“内部”的约束实际上是通过将滚动视图绑定到内容来设置滚动视图的可滚动区域的大小和位置的。

这完全不是显而易见的,因为当您设置约束时,XCode会始终建议当前间距,而您有可能以冲突的方式有意地更改向内和向外的约束,这可能永远不会发生。但是您可以并且它们具有上述含义:一个控制滚动视图的布局,另一个控制可滚动内容区域的大小。

我偶然发现了这一点,然后看到它的工作原理使我进入这篇文章,对其进行了完整的解释,并为此引用了苹果文档来源:

https://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

关于内容的自己确定的大小的最后一个关键信息是:您可能会觉得自己陷入了困境,因为您通常将内容的大小调整为例如父视图的宽度,但是在这种情况下,父视图是scrollview和如上所述-约束不会影响您的内容大小。这里的答案是要记住,您可以将项目限制为视图层次结构中不直接相邻的项目:例如,您可以将内容视图的宽度设置为主视图的宽度,而不是徒劳地尝试使scrollview做到这一点为了你。


2

如果在Interface Builder中单击任何View Controller的Properties图标,则可以在Simulated Metrics中将其设置为“ Freeform”大小,并将主View的大小更改为所需的内容大小。

这样,您可以像创建一个大视图一样创建ScrollView的内容。由于这只是一个模拟指标,因此View Controller会在加载时调整为窗口范围的大小。


2

通过Interface Builder设置UIScrollView并不直观。这是我进行设置的清单:

  1. 选择UIViewController的XIB文件。在界面构建器的“身份检查器”中,将UIView更改为类类型UIScrollView

  2. 在“文件检查器”下,取消选中“自动布局”

  3. 在“属性检查器”下,将大小更改为“自由格式”。然后,您可以手动拉伸滚动视图,也可以在“尺寸检查器”下指定自定义宽度和高度。

  4. 在“身份检查器”中,添加类型为“大小”的名为“ contentSize”的新用户定义的运行时属性,并将其更改为{320,1000}之类的值。您无法再通过编程方式进行设置,因此需要执行此步骤,以便Scroll View知道Scroll View的内容大于窗口的内容。


2

只需在滚动视图上删除autoLayout。那么代码就是这样简单:

scrollviewName.contentSize = CGSizeMake(0, 650);

只需在.h文件上创建一个iboulet属性,然后在.m文件上进行合成。确保启用滚动。


1

是的,st3fan是正确的,必须设置UIScrollView的contentSize属性。但您不应为此目的关闭自动版式。您可以轻松地仅在IB中使用自动布局设置UIScrollView的contentSize,而无需任何代码。

重要的是要理解,当不直接使用UIScrollView的autolayout contentSize时,它是基于UIScrollView的所有子视图的约束来计算的。您所需要做的就是为两个方向的子视图提供适当的约束。

例如,如果您只有一个子视图,则可以设置其顶部和底部到父视图的高度和空间(即本例中的scrollView)contentSize.height计算为总和

Vertical Space (aSubview.top to Superview.top) + aSubview.height + Vertical Space (aSubview.top to Superview.top)

contentSize.width是根据水平约束类似地计算的。

如果没有太多约束可以正确计算contentSize,则“视图控制器场景”项附近会显示一个红色小按钮,以告知布局歧义。

如果有许多子视图,则可能是“约束”的“链”:顶部到顶部的子视图,子视图之间的高度和空间以及最底部的子视图到底部,如Danyal Aytekin的答案。

但实际上,在大多数情况下,仅添加一个具有所需大小的空视图,并将scrollView的顶部,左侧,底部,右侧的空间设置为0更为方便。 您可以将此视图用作“内容视图”,即放置所有其他子视图在它上面,或者如果您已经有很多子视图并且不想再次移动它们并设置布局,则可以将此辅助视图添加到现有子视图中并使其隐藏。

为了使scrollView可滚动,计算出的contentSize必须大于scrollView的大小。


1

您可以在StoryBoard中使用自动版式设置UIScrollView。基本上,您需要的是:

  1. 添加UIScrollView
  2. 向其添加所有约束(如从顶部,左侧,右侧,底部边缘插入的插图)
  3. 将“容器” UIView添加到UIScrollView
  4. 如果只想单向滚动(例如,垂直):显式设置高度(对于实例为600),并将width链接到UIScrollView的宽度。
  5. 如果要进行双向滚动,只需设置宽度和高度即可。

故事板设置



0

我找到一种更方便的方法。

1:缩放滚动视图的大小以在其中包含所有ui。

2:添加滚动视图的iboutlet。

3:在viewDidLoad中,保存滚动视图的frame.size。
(例如_scrollSize = _scrollView.frame.size;)

4:在viewWillAppear中,通过之前保存的CGSize设置contentSize。
(例如_scrollView.contentSize = _scrollSize;)

5:完成〜


0
  1. 添加UIViewController
  2. 在UIViewController中的“属性检查器->模拟指标”中设置大小自由格式
  3. 在UIViewController的“大小检查器->视图控制器”中设置高度800
  4. 在UIViewController中添加UIScrollView
  5. 将所有约束添加到UIScrollView(顶部,左侧,右侧,底部),并添加对齐方式X =中心
  6. 在UIScrollView中添加UIView
  7. 将所有约束添加到UIView(顶部,左侧,右侧,底部),并添加对齐方式X =中心。是的,与#3中的UIScrollView相同,但对于UIView
  8. 将高度限制添加到UIView。例如780

故事板


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.