我在使用 UIKit 中的 UIScrollView 时遇到问题。这是我的代码。我希望我的屏幕能够滚动以查看所有元素。
我无法在我的应用程序中滚动。发生了什么? 我想让它垂直滚动。在这种情况下如何使用 UIScrollView ?我可以使用其他方式滚动视图吗?
class ViewController: UIViewController {
private var image: UIImageView = {
let image = UIImageView()
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
private var image1: UIImageView = {
let image = UIImageView()
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
private var image2: UIImageView = {
let image = UIImageView()
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
private var image3: UIImageView = {
let image = UIImageView()
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
private var image4: UIImageView = {
let image = UIImageView()
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
private var scroll: UIScrollView = {
let scroll = UIScrollView()
scroll.translatesAutoresizingMaskIntoConstraints = false
return scroll
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scroll)
scroll.addSubview(image)
scroll.addSubview(image1)
scroll.addSubview(image2)
scroll.addSubview(image3)
scroll.addSubview(image4)
scroll.addSubview(image5)
let imagetest = UIImage(named: "test")
image.image = imagetest
image1.image = imagetest
image2.image = imagetest
image3.image = imagetest
image4.image = imagetest
NSLayoutConstraint.activate([
scroll.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
scroll.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
scroll.topAnchor.constraint(equalTo: self.view.topAnchor),
scroll.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
image.leadingAnchor.constraint(equalTo: scroll.leadingAnchor),
image.trailingAnchor.constraint(equalTo: scroll.trailingAnchor),
image.topAnchor.constraint(equalTo: scroll.topAnchor, constant: 20),
image.heightAnchor.constraint(equalToConstant: 200),
image.widthAnchor.constraint(equalTo: scroll.widthAnchor),
image1.leadingAnchor.constraint(equalTo: scroll.leadingAnchor),
image1.trailingAnchor.constraint(equalTo: scroll.trailingAnchor),
image1.topAnchor.constraint(equalTo: image.bottomAnchor, constant: 20),
image1.heightAnchor.constraint(equalToConstant: 200),
image1.widthAnchor.constraint(equalTo: scroll.widthAnchor),
image1.widthAnchor.constraint(equalTo: scroll.widthAnchor),
image2.leadingAnchor.constraint(equalTo: scroll.leadingAnchor),
image2.trailingAnchor.constraint(equalTo: scroll.trailingAnchor),
image2.topAnchor.constraint(equalTo: image1.bottomAnchor, constant: 20),
image2.heightAnchor.constraint(equalToConstant: 200),
image2.widthAnchor.constraint(equalTo: scroll.widthAnchor),
image3.leadingAnchor.constraint(equalTo: scroll.leadingAnchor),
image3.trailingAnchor.constraint(equalTo: scroll.trailingAnchor),
image3.topAnchor.constraint(equalTo: image2.bottomAnchor, constant: 20),
image3.heightAnchor.constraint(equalToConstant: 200),
image3.widthAnchor.constraint(equalTo: scroll.widthAnchor),
image4.leadingAnchor.constraint(equalTo: scroll.leadingAnchor),
image4.trailingAnchor.constraint(equalTo: scroll.trailingAnchor),
image4.topAnchor.constraint(equalTo: image3.bottomAnchor, constant: 20),
image4.heightAnchor.constraint(equalToConstant: 200),
image4.widthAnchor.constraint(equalTo: scroll.widthAnchor),
])
}
}
阅读
UIScrollView
和.contentLayoutGuide
和.frameLayoutGuide
为了“可滚动”,UI 元素上的约束必须定义可滚动内容区域。
管理和理解的最简单方法是声明两个属性:
let cg = scroll.contentLayoutGuide
let fg = scroll.frameLayoutGuide
然后将元素约束到这些参考线:
NSLayoutConstraint.activate([
scroll.topAnchor.constraint(equalTo: self.view.topAnchor),
scroll.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
scroll.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
scroll.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
// controls the Top of the scrollable region
image.topAnchor.constraint(equalTo: cg.topAnchor, constant: 20),
// controls the Leading of the scrollable region
image.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
// controls the Trailing - and thus the Width - of the scrollable region
image.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
image.heightAnchor.constraint(equalToConstant: 200),
image.widthAnchor.constraint(equalTo: fg.widthAnchor),
image1.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
// we only need trailing anchor on the widest content element
//image1.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
image1.topAnchor.constraint(equalTo: image.bottomAnchor, constant: 20),
image1.heightAnchor.constraint(equalToConstant: 200),
image1.widthAnchor.constraint(equalTo: fg.widthAnchor),
image2.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
// we only need trailing anchor on the widest content element
//image2.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
image2.topAnchor.constraint(equalTo: image1.bottomAnchor, constant: 20),
image2.heightAnchor.constraint(equalToConstant: 200),
image2.widthAnchor.constraint(equalTo: fg.widthAnchor),
image3.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
// we only need trailing anchor on the widest content element
//image3.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
image3.topAnchor.constraint(equalTo: image2.bottomAnchor, constant: 20),
image3.heightAnchor.constraint(equalToConstant: 200),
image3.widthAnchor.constraint(equalTo: fg.widthAnchor),
image4.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
// we only need trailing anchor on the widest content element
//image4.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
image4.topAnchor.constraint(equalTo: image3.bottomAnchor, constant: 20),
image4.heightAnchor.constraint(equalToConstant: 200),
image4.widthAnchor.constraint(equalTo: fg.widthAnchor),
// controls the Bottom - and thus the Height - of the scrollable region
image4.bottomAnchor.constraint(equalTo: cg.bottomAnchor),
])
UIScrollView 有两个您应该使用的特殊布局指南:
frameLayoutGuide
和 contentLayoutGuide
。前者用于调整滚动视图本身的大小和位置。后者用于调整滚动视图中内容的大小和位置。
将您的约束更新为以下内容,使其按预期工作:
NSLayoutConstraint.activate([
// Size and position the scroll view within the view controller
scroll.frameLayoutGuide.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
scroll.frameLayoutGuide.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
scroll.frameLayoutGuide.topAnchor.constraint(equalTo: self.view.topAnchor),
scroll.frameLayoutGuide.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
// Ensure content view width is the same width as the scrollview
scroll.contentLayoutGuide.widthAnchor.constraint(equalTo: scroll.frameLayoutGuide.widthAnchor),
// Size and position the image within the content view
image.leadingAnchor.constraint(equalTo: scroll.contentLayoutGuide.leadingAnchor),
image.trailingAnchor.constraint(equalTo: scroll.contentLayoutGuide.trailingAnchor),
image.topAnchor.constraint(equalTo: scroll.contentLayoutGuide.topAnchor, constant: 20),
image.heightAnchor.constraint(equalToConstant: 200),
image1.leadingAnchor.constraint(equalTo: scroll.contentLayoutGuide.leadingAnchor),
image1.trailingAnchor.constraint(equalTo: scroll.contentLayoutGuide.trailingAnchor),
image1.topAnchor.constraint(equalTo: image.bottomAnchor, constant: 20),
image1.heightAnchor.constraint(equalToConstant: 200),
image2.leadingAnchor.constraint(equalTo: scroll.contentLayoutGuide.leadingAnchor),
image2.trailingAnchor.constraint(equalTo: scroll.contentLayoutGuide.trailingAnchor),
image2.topAnchor.constraint(equalTo: image1.bottomAnchor, constant: 20),
image2.heightAnchor.constraint(equalToConstant: 200),
image3.leadingAnchor.constraint(equalTo: scroll.contentLayoutGuide.leadingAnchor),
image3.trailingAnchor.constraint(equalTo: scroll.contentLayoutGuide.trailingAnchor),
image3.topAnchor.constraint(equalTo: image2.bottomAnchor, constant: 20),
image3.heightAnchor.constraint(equalToConstant: 200),
image4.leadingAnchor.constraint(equalTo: scroll.contentLayoutGuide.leadingAnchor),
image4.trailingAnchor.constraint(equalTo: scroll.contentLayoutGuide.trailingAnchor),
image4.topAnchor.constraint(equalTo: image3.bottomAnchor, constant: 20),
image4.bottomAnchor.constraint(equalTo: scroll.contentLayoutGuide.bottomAnchor, constant: -20),
image4.heightAnchor.constraint(equalToConstant: 200),
])
所有图像都将其水平位置设置为内容指南的前导和尾随锚点。这隐式地给出了每个图像的宽度,因此无需设置图像宽度。
第一张图片的顶部固定在内容指南的顶部。
最后一张图片的底部固定在内容指南的底部。
内容指南的宽度设置为滚动视图的宽度,因此没有水平滚动。