UIScrollView with dynamically sized content(具有动态大小内容的 UIScrollView)
问题描述
(Xcode 11,斯威夫特)
(Xcode 11, Swift)
作为 iOS 和 Autolayout 的新手,我正在努力实现一个相当简单的 (恕我直言) 视图,该视图显示 [垂直] 项目列表.唯一的问题是项目是动态决定的,每个项目都可以是文本或图像(其中任何一个都可能相当大,因此需要滚动).WebView 不是一个选项,因此必须在本地实现.
Being a newbie to iOS and Autolayout, I'm struggling with implementing a fairly simple (IMHO) view which displays a [vertical] list of items. The only problem is that items are decided dynamically and each of them could be either text or image (where either of those could be fairly large so scrolling would be required). WebView is not an option, so it has to be implemented natively.
我是这样理解这个过程的:
This is how I understand the process:
- 在 IB 中创建一个 UIScrollView 并将其调整为外框的大小.
- 将容器视图作为 UIScrollView 的子视图(同样,在 IB 中)并将其大小设置为相同.
- 设置两个宽度相等的约束
- 在运行时,使用 UILabels/UIImageViews 填充容器视图,并以编程方式设置约束以确保正确布局.
- 告诉"滚动视图关于子视图的高度,以使其管理其滚动.
这是正确的方法吗?它似乎对我不起作用(对于一个将非常高的图像动态添加到容器视图的玩具示例 - 我无法让滚动工作).在上述过程中执行最后一步的正确方法是什么 - 只需将滚动视图的 contentSize 强制为填充容器视图的大小(它似乎对我不起作用).任何帮助将不胜感激.
Is this the right approach? It doesn't seem to work for me (for a toy example of dynamically adding a very tall image to a container view - I cannot get the scrolling to work). What would be the proper way to do the last step in the process above - just force the contentSize of the scrollview to the size of the populated container view (it doesn't seem to work for me). Any help would be appreciated.
推荐答案
在运行时向滚动视图添加多个元素时,您可能会发现使用 UIStackView
更容易...如果设置正确,它会随着每个添加的对象自动增加高度.
When adding multiple elements to a scroll view at run-time, you may find it much easier to use a UIStackView
... when setup properly, it will automatically grow in height with each added object.
举个简单的例子……
1) 首先添加一个 UIScrollView
(我给它一个蓝色背景以便于查看).将其在所有 4 个方面都限制为零:
1) Start by adding a UIScrollView
(I gave it a blue background to make it easier to see). Constrain it to Zero on all 4 sides:
请注意,我们看到红色圆圈"表示缺少/冲突的约束.暂时忽略它.
Note that we see the "red circle" indicating missing / conflicting constraints. Ignore that for now.
2) 在滚动视图中添加一个 UIView
作为内容视图"(我给它一个 systemYellow 背景以便于查看).在内容布局指南的所有 4 个方面将其限制为零——这将(最终)定义滚动视图的内容大小.还要将其限制为等宽和等高框架布局指南:
2) Add a UIView
as a "content view" to the scroll view (I gave it a systemYellow background to make it easier to see). Constrain it to Zero on all 4 sides to the Content Layout Guide -- this will (eventually) define the scroll view's content size. Also constrain it equal width and equal height to the Frame Layout Guide:
重要步骤: 选择高度约束,然后在 Size Inspector
窗格中选择 Placeholder - Remove at build time
复选框.这将在设计时满足 IB 中的自动布局,但将允许该视图的高度根据需要缩小/增长.
Important Step: Select the Height constraint, and in the Size Inspector
pane select the Placeholder - Remove at build time
checkbox. This will satisfy auto-layout in IB during design time, but will allow the height of that view to shrink / grow as necessary.
3) 添加一个垂直的 UIStackView
到内容视图".将其在所有 4 个面上都约束为零.将其属性配置为Fill/Fill/8
(如下图):
3) Add a Vertical UIStackView
to the "content view". Constrain it to Zero on all 4 sides. Configure its properties to Fill / Fill / 8
(as shown below):
4) 在视图控制器类中添加一个 @IBOutlet
连接到堆栈视图.现在,在运行时,当您将 UI 元素添加到堆栈视图时,您的所有可滚动性"都将由自动布局处理.
4) Add an @IBOutlet
connection to the stack view in your view controller class. Now, at run-time, as you add UI elements to the stack view, all of your "scrollability" will be handled by auto-layout.
这是一个示例类:
class DynaScrollViewController: UIViewController {
@IBOutlet var theStackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
// local var so we can reuse it
var theLabel = UILabel()
var theImageView = UIImageView()
// create a new label
theLabel = UILabel()
// this gets set to false when the label is added to a stack view,
// but good to get in the habit of setting it
theLabel.translatesAutoresizingMaskIntoConstraints = false
// multi-line
theLabel.numberOfLines = 0
// cyan background to make it easy to see
theLabel.backgroundColor = .cyan
// add 9 lines of text to the label
theLabel.text = (1...9).map({ "Line ($0)" }).joined(separator: "
")
// add it to the stack view
theStackView.addArrangedSubview(theLabel)
// add another label
theLabel = UILabel()
// multi-line
theLabel.numberOfLines = 0
// yellow background to make it easy to see
theLabel.backgroundColor = .yellow
// add 5 lines of text to the label
theLabel.text = (1...5).map({ "Line ($0)" }).joined(separator: "
")
// add it to the stack view
theStackView.addArrangedSubview(theLabel)
// create a new UIImageView
theImageView = UIImageView()
// this gets set to false when the label is added to a stack view,
// but good to get in the habit of setting it
theImageView.translatesAutoresizingMaskIntoConstraints = false
// load an image for it - I have one named background
if let img = UIImage(named: "background") {
theImageView.image = img
}
// let's give the image view a 4:3 width:height ratio
theImageView.widthAnchor.constraint(equalTo: theImageView.heightAnchor, multiplier: 4.0/3.0).isActive = true
// add it to the stack view
theStackView.addArrangedSubview(theImageView)
// add another label
theLabel = UILabel()
// multi-line
theLabel.numberOfLines = 0
// yellow background to make it easy to see
theLabel.backgroundColor = .green
// add 2 lines of text to the label
theLabel.text = (1...2).map({ "Line ($0)" }).joined(separator: "
")
// add it to the stack view
theStackView.addArrangedSubview(theLabel)
// add another UIImageView
theImageView = UIImageView()
// this gets set to false when the label is added to a stack view,
// but good to get in the habit of setting it
theImageView.translatesAutoresizingMaskIntoConstraints = false
// load a different image for it - I have one named AquariumBG
if let img = UIImage(named: "AquariumBG") {
theImageView.image = img
}
// let's give this image view a 1:1 width:height ratio
theImageView.heightAnchor.constraint(equalTo: theImageView.widthAnchor, multiplier: 1.0).isActive = true
// add it to the stack view
theStackView.addArrangedSubview(theImageView)
}
}
如果已遵循这些步骤,您应该会得到以下输出:
If the steps have been followed, you should get this output:
并且,在滚动到底部之后:
and, after scrolling to the bottom:
这篇关于具有动态大小内容的 UIScrollView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:具有动态大小内容的 UIScrollView
基础教程推荐
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01