令人惊讶的是,这比我想象的要难。我遵循这个教程,这似乎相当简单,但我通过编程创建我的视图,而不是使用故事板。需要说明的是,我添加到内容视图中的内容是静态的,即它不会增长或增加。
下面是滚动视图和内容视图的定义:
lazy var contentView : UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var scrollView : UIScrollView = {
let scrollView = UIScrollView(frame: .zero)
scrollView.backgroundColor = .white
scrollView.frame = self.view.bounds
scrollView.bounces = true
scrollView.autoresizingMask = .flexibleHeight
scrollView.contentSize = CGSize(width: self.view.frame.width, height: contentView.frame.height)
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
在viewdidload中添加滚动视图并在视图控制器中设置其约束:
view.addSubview(scrollView)
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
然后我添加内容视图和约束:
scrollView.addSubview(contentView)
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
contentView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
let constraint = contentView.heightAnchor.constraint(equalTo: view.heightAnchor)
constraint.priority = UILayoutPriority(250)
constraint.isActive = true
问题是我不能一直滚动到底部。
初始注意事项
删除scrollView.frame = self.view.bounds
给scrollView
一个frame
是没有意义的,因为你稍后会通过使用约束给它一个框架。
scrollView.autoresizingMask = .flexibleHeight
你正在使用约束,而不是自动调整大小蒙版,给滚动视图它的框架和以后的调整大小行为。
删除scrollView.contentSize = CGSize(width: self.view.frame.width, height: contentView.frame.height)
一旦滚动视图受到约束的影响,你必须使用约束,而不是contentSize
,给它一个决定滚动行为的内容大小。
添加内容视图
有了这些基础,让我们讨论一下如何将内容视图添加到滚动视图:
scrollView.addSubview(contentView)
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
这并不是完全错误的,但它是非常过时的。你应该把内容视图固定在滚动视图的内容布局指南上;这就是它的作用。所以,在你有equalTo: scrollView
的地方,把它改成equalTo: scrollView.contentLayoutGuide
。
好吧!现在一切都组装好了,我们准备讨论滚动。在这个配置中,使滚动视图可滚动的是内容视图比滚动视图本身大。到目前为止,这还不是真的;事实上,内容视图根本没有大小。所以我们必须给它一个大小。
你那样做的企图是相当微弱的。让我们提取给内容视图高度和宽度限制的关键行:contentView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
contentView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
(删除其他两行,因为它们现在没有真正做任何有用的事情。)内容视图比滚动视图大吗?好吧,也许,但如果是这样,只有一点点,因为内容视图只是主视图的大小,和滚动视图是相同的大小或稍微小一点。
因为我们只是在演示,所以最好让内容视图比滚动视图大很多,这样我们就可以进行一些主要的滚动。将第二行更改为:
contentView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier:2 ).isActive = true
是的,宝贝!现在我们可以真正滚动了
使内容更可见
仍然很难看到发生了什么(所有的东西都是白色的),所以我建议你用一些颜色填充内容视图,这将允许我们看到发生了什么。如下声明一个自绘制视图:
class MyView : UIView {
override class var layerClass : AnyClass { CAGradientLayer.self }
override func willMove(toSuperview newSuperview: UIView?) {
let lay = self.layer as! CAGradientLayer
lay.colors = [UIColor.red.cgColor, UIColor.green.cgColor]
}
}
现在改变
let view = UIView()
let view = MyView()
现在当你滚动到底部时,它是非常明显的;真正的绿色在底部。
总结下面是改正后的完整代码:
class MyView : UIView {
override class var layerClass : AnyClass { CAGradientLayer.self }
override func willMove(toSuperview newSuperview: UIView?) {
let lay = self.layer as! CAGradientLayer
lay.colors = [UIColor.red.cgColor, UIColor.green.cgColor]
}
}
class ViewController: UIViewController {
lazy var contentView : UIView = {
let view = MyView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var scrollView : UIScrollView = {
let scrollView = UIScrollView(frame: .zero)
scrollView.backgroundColor = .white
scrollView.bounces = true
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
scrollView.addSubview(contentView)
contentView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor).isActive = true
contentView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
contentView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier:2 ).isActive = true
}
}