如何在Interface Builder中使用UIScrollView?

虽然我以前通过编程方式成功地使用了UIScrollView ,但是我无法通过在Interface Builder中完全设置它来工作。

我在我的iPhone应用程序中有一个简单的“关于”页面。 它有一个UITextView ,一些图标,并链接到我的其他应用程序。 我已经将所有这些视图添加到了我的UIScrollView ,并将它们整理为大于480.当我启动我的应用程序时,滚动视图只显示适合屏幕的内容,而不滚动。

是否有可能完全通过IB做到这一点,或者我必须通过代码操纵contentSize?

你忘了设置UIScrollView的contentSize属性。 奇怪的是,你不能从Interface Builder中做到这一点。 您将必须从pipe理此滚动视图的视图控制器执行此操作。

Boby_Wan的回答让我想到了,我发现下面的解决scheme来从Interface BuilderconfigurationUIScrollView的contentSize:

  1. 在Storyboard场景中selectUIScrollView
  2. 转到“ 标识”检查器 ,创build一个新的“ 用户定义的运行属性” (单击“+”button)
  3. 将属性键path更改为contentSize
  4. 将属性types更改为Size
  5. 现在将设置为{ 所需的内容宽度所需的内容高度 }

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

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

当我第一次这样做,我收到以下错误:

非法configuration:
使用4.3之前的Xcode版本的大小types用户定义的运行时属性
MainStoryboard.storyboard

如果你也得到这个错误,很容易解决:在Project Navigator中selectStoryboard,然后调出File inspector 。 find/展开接口生成器文档部分,并有一个下拉开发 。 确保这是设置为Xcode 4.3

借助Autolayout(iOS6 +),您可以避免设置contentSize 。 请改为设置以下约束:

  1. 将滚动视图的顶部固定到其最顶层的孩子的顶部。
  2. 并把它的底部固定在其最底部的小孩的底部。

您只能使用Interface Builder来执行此操作,转到Identity Inspector(第三个检查器选项卡),并添加一个新的User Defined Runtime属性

  • 关键path: contentSize
  • types: 大小
  • 值: {宽度,高度}

现在有一种方法可以在不离开Storyboard的情况下进行UIScrollView滚动:

  1. selectStoryboard中的UIScrollView ,转到大小检查器 ,并将Content Insets部分中的Bottom值(或任何其他需要更改的值)更改为内容区域的高度。
  2. 现在转到Identity检查器并创build一个新的用户定义的运行时属性 (通过单击+button)并将其命名为contentSize 。 无论您填写什么types ,都无关紧要(您甚至可以保留其默认值)。

这将使UIScrollView正常工作,虽然我不知道为什么第二步是必要的(我偶然发现)。 🙁

在使用Autolayout的Xcode 4.5中,我的大小检查器中没有Content Insets部分。 所以我不得不在用户定义的运行时属性下添加它,然后它工作正常。

你在“用户定义的运行时属性”中添加的内容是keyPath == contentInset,其types是“Rect”(UIEdgeInsets,它与Rect有相同的input),定义为{top,left},{bottom,right}。 contentSize只定义了滚动视窗的区域。 contentInset定义了可滚动区域。

我希望这有助于在相同的情况下的人。

我过去使用过的一种方法是将scrollview从包含视图的界面构build器中拖出来,并将其实际大小设置为contentSize的值。

界面生成器本身并不明显的是,你可以拥有存储在笔尖中的非关联视图,但不是主要用于笔尖的主视图的一部分。

在视图中你想要的滚动视图生活,放置一个简单的UIView,你用作占位符。 (这是简单的,所以你可以直观地devise它的位置,如果你只是使用整个视图,你可以跳过这一步,并使用我提供的第二个代码片段在这个答案的结尾)。

然后你可以使用控件填充滚动视图,从视觉上展示出你想要的方式。 在你的视图控制器中同时提供占位符和滚动视图属性,以便在运行时访问它们。

在运行时,在 – (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]; 

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

如果在Interface Builder中单击任何View Controller的“属性”图标,则可以在“模拟度量标准”中将其设置为“自由forms”大小,并将主视图的大小更改为所需的内容大小。

这样,您就可以像创build一个大视图一样创buildScrollView的内容。 由于它只是一个模拟度量,所以在视图控制器加载时,它将被调整到窗口的边界。

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

  1. selectUIViewController的XIB文件。 在界面生成器的“标识检查器”中,将UIView更改为类typesUIScrollView

  2. 在“文件检查器”下,取消选中Autolayout

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

  4. 在“Identity Inspector”中,添加一个名为“contentSize”的新的“用户定义运行时属性”,types为“Size”,并将其更改为类似{320,1000}的值。 你不能以编程方式设置它,因此需要这一步,以便滚动视图知道滚动视图的内容比窗口大。

只需移除你的滚动视图的autoLayout。 那么代码就像这样简单:

 scrollviewName.contentSize = CGSizeMake(0, 650); 

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

是的, st3fan是正确的,必须设置UIScrollView的contentSize属性。 但是,您不应该为此closures自动布局。 您只需在IB中自动布局,即可轻松设置UIScrollView的contentSize,无需任何代码。

理解使用自动布局的时候很重要,UIScrollView的contentSize不是直接设置的,而是根据UIScrollView的所有子视图的约束来计算的。 所有你需要的是为两个方向的子视图提供适当的限制。

例如,如果你只有一个子视图,你可以设置它的高度和空间从顶部和底部超级查看(即在我们的情况下scrollView)contentSize.height计算为总和

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

contentSize.width的计算方式与水平约束类似。

如果计算contentSize的约束太less,则在“视图控制器场景”项目旁边显示小红色button,以通知布局不明确。

如果有许多子视图,那么它可能是约束的“链”:从顶到顶的子视图,子视图和最底层子视图之间的空间到底部,就像Danyal Aytekin的答案。

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

要使scrollView可滚动计算的contentSize必须大于scrollView的大小。

您可以在StoryBoard中使用Autolayouts制作UIScrollView。 基本上你需要什么是:

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

故事板设置

上面的许多答案都是误导或过时的。 截至2017年(可能更早),界面构build器确实支持带有自动大小内容的滚动视图。 诀窍在于,XCode为scrollview和内部内容之间的约束提供了一个特殊的,非标准的含义。 这些“内在”限制实际上不会影响内容的大小,因为您可能会预期的。

这意味着你可以让你的scrollview固定在主视图的底部,没有空白,也可以将你的滚动视图的内容固定在滚动视图的底部,没有空白,但是内容不会被这个延伸。 相反,内容将获得其自定义大小(更多下面),这也将是滚动视图内的可滚动区域的大小。

像这样想 – 绑定约束到scrollview中有一个不对称:从scrollview到“outside”(父)世界的约束决定了scrollview的大小和位置。 但是,在“滚动视图”内部的约束是通过绑定到内容来真正设置滚动视图的可滚动区域的大小和位置。

这是完全不明显的,因为当你去设置约束时,XCode总是会提示当前的间距,你可能永远不会想到以有冲突的方式有意改变内部和外部的约束。 但是你可以和他们有上面描述的含义:一个控制滚动视图布局,一个控制可滚动的内容区域大小。

我无意中偶然发现了这个问题,然后看到它是如何工作的,这引导我完全解释了这篇文章,并引用了苹果公司的文档来源:

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

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

这里有一个解决scheme来deviseScrollView的内容大于屏幕上的内容,完全在Storyboard中(几乎完全是,你还需要添加一行代码)

https://stackoverflow.com/a/19476991/1869369

我find了一个更方便的方法。

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

2:添加滚动视图的iboutlet。

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

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

5:完成〜

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

故事板