ios 如何在界面生成器中使用 UIScrollView?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1135163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:11:03  来源:igfitidea点击:

how do I use UIScrollView in Interface Builder?

iosiphoneuiscrollviewinterface-builder

提问by George Armhold

While I've used UIScrollViewsuccessfully in the past by manipulating it programmatically, I'm having trouble getting it to work by setting it up exclusively in Interface Builder.

虽然我UIScrollView过去通过以编程方式操作它成功地使用了它,但我无法通过在 Interface Builder 中专门设置它来使其工作。

I have a simple "about" page in my iPhone app. It has a UITextView, some icons, and links to my other apps. I have added all of these views to my UIScrollView, arranging them so that their total size is > 480. When I launch my app, the scrollview displays only the contents that fit on the screen, and nothing scrolls.

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

Is it possible to do this entirely via IB, or must I manipulate the contentSize via code?

是否可以完全通过 IB 执行此操作,还是必须通过代码操作 contentSize?

回答by Stefan Arentz

You forgot to set the contentSize property of the UIScrollView. Strangely enough you can not do this from Interface Builder. You will have to do it from the view controller managing this scroll view.

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

回答by Herr Grumps

Boby_Wan's answer got me thinking, and I found the following solution to configure the UIScrollView's contentSize from Interface Builder:

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

  1. Select the UIScrollViewin the Storyboard scene
  2. Go to the Identity inspector, create a new User Defined Runtime Attribute(click the + button)
  3. Change the attribute Key Pathto contentSize
  4. Change the attribute Typeto Size
  5. Now set the Valueto {desired content width, desired content height}
  1. UIScrollView在 Storyboard 场景中选择
  2. 转到身份检查器,创建一个新的用户定义的运行时属性(单击 + 按钮)
  3. 将属性Key Path更改为contentSize
  4. 将属性类型更改为Size
  5. 现在将设置为{所需内容宽度所需内容高度}

eg setting the value to {320, 920} will let the user scroll down a whole extra screen on the iPhone.

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

(I am using xcode 4.3.3, the project's iOS Deployment Targetis 5.1)

When I first did this I received the following error:

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

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

Illegal Configuration:
     Size type user defined runtime attributes with Xcode versions prior to 4.3
     MainStoryboard.storyboard

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

If you too get this error it is simple to fix: select the Storyboard in the Project Navigator, and bring up the File inspector. Find/expand the Interface Builder Documentsection, and there is a drop down for Development. Ensure this is set to Xcode 4.3

如果您也遇到此错误,修复方法很简单:在Project Navigator 中选择 Storyboard ,然后打开File inspector。找到/展开Interface Builder Document部分,然后有一个Development下拉菜单。确保将其设置为Xcode 4.3

回答by Danyal Aytekin

With Autolayout (iOS6+), you can avoid setting contentSize. Set the following constraints instead:

使用 Autolayout (iOS6+),您可以避免设置contentSize. 改为设置以下约束:

  1. Pin the top of the scrollview to the top of its top-most child.
  2. And pin the bottom to the bottom of its bottom-most child.
  1. 将滚动视图的顶部固定到其最顶层子项的顶部。
  2. 并将底部固定到其最底部的孩子的底部。

回答by Anton Banchev

You can do it using only Interface Builder, go to the Identity Inspector (the third inspector tab) and add a new User Defined Runtimeattribute with

您可以只使用 Interface Builder,转到 Identity Inspector(第三个检查器选项卡)并添加一个新的 User Defined Runtime属性

  • Key Path:contentSize
  • Type:Size
  • Value:{width, height}
  • 关键路径:contentSize
  • 类型:尺寸
  • 值:{宽度,高度}

回答by RoberRM

Now there is a way to make a UIScrollViewscroll without leaving Storyboard:

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

  1. Select the UIScrollViewin the Storyboard, go to the Size inspectorand change the Bottomvalue (or whatever other value you need to change) in the Content Insetssection to the height of the content area.
  2. Now go to the Identity inspectorand create a new User Defined Runtime Attribute(by clicking the + button) and name it contentSize. It doesn't matter what Typeor Valueyou fill in (you can even leave their default value).
  1. 选择UIScrollView在故事板,转到尺寸检查和更换底部的值(或者任何你需要改变其他值)内容插图部分内容区域的高度。
  2. 现在转到身份检查器并创建一个新的用户定义的运行时属性(通过单击 + 按钮)并将其命名为contentSize. 您填写的类型无关紧要(您甚至可以保留它们的默认值)。

This will make the UIScrollViewwork properly, although I don't know why the second step is necessary (I found out by chance). :(

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

回答by unsynchronized

one approach i have used in the past is to drag the scrollview out of it's containing view in interface builder, and set it's actual size to what want the contentSize to be.

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

what is not inherently obvious about interface builder is you can have unassociated views that are stored in the nib, but aren't a part of the main view the nib is primarily for.

界面构建器本质上并不明显的是,您可以将未关联的视图存储在笔尖中,但不是笔尖主要用于的主视图的一部分。

in the view where you want it the scrollview to live, place a simple UIView, which you use as a place holder. (this is simply so you can visually design it's location. if you are just using the entire view, you can skip this step and use the second code snippet i supply at the end of this answer).

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

you can then populate the scrollview with controls, visually laying it out how you want it to be. give both the placeholder and the scrollview properties inside your view controller so you an access them at runtime.

然后,您可以使用控件填充滚动视图,直观地将其布局为您想要的方式。在视图控制器中同时提供占位符和滚动视图属性,以便您在运行时访问它们。

at runtime, in - (void)viewDidLoad

在运行时,在 - (void)viewDidLoad

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

alternatively (if you didn't use a placeholder):

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

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

finally, if you "lose" your scroll view in interface builder (it's possible to close it so it disappears from the design grid), don't panic. just click on it in the object list to the left of the design grid.

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

回答by Robert Wasmann

In Xcode 4.5 using Autolayout I have no Content Insets section in my size inspector. So I had to add it under User Defined Runtime Attributes and then it worked fine.

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

What you add in "User Defined Runtime Attributes" is keyPath == contentInset which is of type "Rect" (UIEdgeInsets, which has the same input as a Rect) and is defined as {top, left},{bottom, right}. The contentSize only defines the region of the scrollview window. contentInset defines the scrollable area.

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

I hope this helps somebody in the same situation.

我希望这可以帮助处于相同情况的人。

回答by Pat Niemeyer

Many of the answers above are misleading or outdated. As of 2017 (possibly much earlier) interface builder doessupport scrollviews with automatically sized content. The trick is that XCode gives a special, non-standard meaning to the constraints between the scrollview and the content inside it. These "inward" constraints will notactually affect the size of the content as you might otherwise expect.

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

This means that you can e.g. have your scrollview pinned to the bottom of the main view with zero margin, and also have your scrollview's content pinned to the bottom of the scrollview with zero margin, but the content will not actually be stretched by this. Instead the content will get its self-determined size (more below) and this will also be the size of the scrollable area within the scrollview.

这意味着您可以将滚动视图固定到主视图的底部,边距为零,也可以将滚动视图的内容固定到滚动视图的底部,边距为零,但内容实际上不会因此而拉伸。相反,内容将获得其自行确定的大小(更多见下文),这也将是滚动视图内可滚动区域的大小。

Think of it like this - There is an asymmetry in binding constraints to a scrollview: Constraints from the scrollview to the "outside" (parent) world determine the size and position of the scrollview as usual. But constraints "inside" the scrollview are really setting the size and position of the scrollable area of the scrollview, by binding it to the content.

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

This is totally non-obvious because when you go to set the constraints XCode will always suggest the current spacing and it might never occur to you to intentionally change the inward and outward facing constraints in a way that conflicts. But you can and they have the meaning described above: one controls the scrollview layout and one controls the scrollable content area size.

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

I stumbled upon this by accident and then seeing how it appeared to work lead me to this article that explains it completely and cites the Apple docs source for this:

我偶然发现了这个,然后看到它是如何工作的,这让我看到了这篇文章,它完全解释了它,并为此引用了 Apple 文档源:

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

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

One last critical piece of information, about the content's self-determined size: You may feel that you are in a catch-22 here because you normally size your content to e.g. the parent view's width, but in this case the parent is the scrollview and as described above - the constraint will not affect your content size. The answer here is to remember that you can constrain items to items not directly neighboring in your view hierarchy: e.g. You can set the width of your content view to the width of the main view instead of trying in vain to get the scrollview to do it for you.

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

回答by Aldrin Equila

Just remove the autoLayout on your scrollview. then the code is as simple as this:

只需删除滚动视图上的自动布局。那么代码就这么简单:

scrollviewName.contentSize = CGSizeMake(0, 650);

just create an iboulet property on .h file then synthesize on .m file. Make sure that the scrolling is enabled.

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

回答by oliland

If you click on the Properties icon of any View Controller in Interface Builder, you can set it to a "Freeform" size in Simulated Metrics and change the size of the main View to be your desired content size.

如果您单击 Interface Builder 中任何 View Controller 的 Properties 图标,您可以在 Simulated Metrics 中将其设置为“自由格式”大小,并将主视图的大小更改为您想要的内容大小。

This way you can create your ScrollView's content as if it were one large view. As it's only a simulated metric your View Controller will be resized to the window's bounds when it's loaded.

通过这种方式,您可以像创建一个大视图一样创建 ScrollView 的内容。由于它只是一个模拟指标,因此您的视图控制器将在加载时调整到窗口的边界。