swift - Swift:以编程方式添加视图时,UIScrollView 的可滚动内容大小不明确,而不使用 IB
问题描述
我在不使用情节提要的情况下以编程方式创建我的视图。当调试视图层次结构打开时,我从 Xcode 中得到这个问题“运行时:布局问题:UIScrollView 的可滚动内容大小不明确”。我认为这意味着对 scollView 的限制尚不清楚。
我可以看到 scrollView 在视图层次结构中显示(黄色之一),但它的子视图 UIView 不是。使用故事板/IB 找到一些解决方案,尽管我无法将其与我的代码联系起来。任何提示和建议表示赞赏。
下面是scrollView的结构。
ScrollView
->UIView as contentView(coverImageContainer)
-> UIImageView(coverArtImageView)
-> UIButton
// scroller
lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
// scrollView.contentMode = .scaleToFill
scrollView.contentInsetAdjustmentBehavior = .never
scrollView.alwaysBounceVertical = true
scrollView.backgroundColor = .yellow
return scrollView
}()
// cover image
lazy var coverImageContainer: UIView = {
let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
return containerView
}()
lazy var coverArtImageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
imageView.layer.cornerRadius = 5
return imageView
}()
lazy var dismissChevron: UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.addTarget(self, action: #selector(disimissAction), for: .touchUpInside)
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
backingImageView.image = backingImage
view.addSubview(backingImageView)
view.addSubview(dimmerLayer)
view.addSubview(scrollView)
scrollView.addSubview(coverImageContainer)
scrollView.addSubview(stretchySkirt)
coverImageContainer.addSubview(coverArtImageView)
coverImageContainer.addSubview(dismissChevron)
// set layout constraint
configureLayout()
...
}
func configureLayout() {
let g = view.safeAreaLayoutGuide
backingImageleadInset = backingImageView.leadingAnchor.constraint(equalTo: g.leadingAnchor)
backingImageTrailingInset = backingImageView.trailingAnchor.constraint(equalTo: g.trailingAnchor)
backingImageTopInset = backingImageView.topAnchor.constraint(equalTo: view.topAnchor)
backingImageBottomInset = backingImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
NSLayoutConstraint.activate([
backingImageleadInset,
backingImageTrailingInset,
backingImageTopInset,
backingImageBottomInset,
dimmerLayer.leadingAnchor.constraint(equalTo: g.leadingAnchor),
dimmerLayer.trailingAnchor.constraint(equalTo: g.trailingAnchor),
dimmerLayer.topAnchor.constraint(equalTo: view.topAnchor),
dimmerLayer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: backingImageView.topAnchor, constant: 15),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
coverImageContainer.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
coverImageContainer.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 57),
coverImageContainer.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
coverImageContainer.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
coverImageContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -237),
stretchySkirt.topAnchor.constraint(equalTo: coverImageContainer.bottomAnchor),
stretchySkirt.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
stretchySkirt.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
stretchySkirt.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
coverArtImageView.centerXAnchor.constraint(equalTo: coverImageContainer.centerXAnchor),
coverArtImageView.topAnchor.constraint(equalTo: coverImageContainer.topAnchor, constant: 38),
coverArtImageView.leadingAnchor.constraint(equalTo: coverImageContainer.leadingAnchor, constant: 20),
coverArtImageView.trailingAnchor.constraint(equalTo: coverImageContainer.trailingAnchor, constant: -20),
// coverArtImageView.widthAnchor.constraint(equalToConstant: 354),
coverArtImageView.heightAnchor.constraint(equalTo: coverArtImageView.widthAnchor),
dismissChevron.centerXAnchor.constraint(equalTo: coverImageContainer.centerXAnchor),
dismissChevron.topAnchor.constraint(equalTo: coverImageContainer.topAnchor, constant: 4),
])
}
解决方案
正如 DongMag 的评论,我现在解决了这个问题。
我想要达到的效果如下图所示。就像 Apple Music 的 Max Card View。
好吧,问题出在coverImageContainer
's 约束上,我应该将其约束为 view 或 view.safeAreaLayoutGuide 而不是 scrollView。因为我不想coverImageContainer
滚动。
在这里更新我的代码,如果将来有人遇到同样的问题,他们可能会做参考:
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
. . .
scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: backingImageView.topAnchor, constant: 15),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
coverImageContainer.centerXAnchor.constraint(equalTo: g.centerXAnchor),
coverImageContainer.topAnchor.constraint(equalTo: g.topAnchor, constant: 57),
coverImageContainer.leadingAnchor.constraint(equalTo: g.leadingAnchor),
coverImageContainer.trailingAnchor.constraint(equalTo: g.trailingAnchor),
coverImageContainer.heightAnchor.constraint(equalTo: coverImageContainer.widthAnchor),
stretchySkirt.topAnchor.constraint(equalTo: coverImageContainer.bottomAnchor),
stretchySkirt.leadingAnchor.constraint(equalTo: g.leadingAnchor),
stretchySkirt.trailingAnchor.constraint(equalTo: g.trailingAnchor),
stretchySkirt.bottomAnchor.constraint(equalTo: view.bottomAnchor),
coverArtImageView.centerXAnchor.constraint(equalTo: coverImageContainer.centerXAnchor),
coverArtImageView.topAnchor.constraint(equalTo: coverImageContainer.topAnchor, constant: 38),
coverArtImageView.leadingAnchor.constraint(equalTo: coverImageContainer.leadingAnchor, constant: 38),
coverArtImageView.heightAnchor.constraint(equalTo: coverArtImageView.widthAnchor),
dismissChevron.centerXAnchor.constraint(equalTo: coverImageContainer.centerXAnchor),
dismissChevron.topAnchor.constraint(equalTo: coverImageContainer.topAnchor, constant: 4),
])
推荐阅读
- elasticsearch - elasticsearch 条件 Boost 索引时间和查询时间
- java - 在 Spark 中使用侦听器计算数据库加载时间
- html - 为什么 attr 不能在 jquery 中输入?
- python - 如何从mac中删除VScode中的旧版本python?
- javascript - 如何在反应中有条件地渲染样式化的组件?
- binary-tree - 你如何找到完全二叉树最低层的叶子数?
- docker - 当 docker build 运行 Dockerfile 时使用来自 bitbucket 的节点缓存依赖项
- amazon-s3 - 使用 c++ S3 SDK,带有 Minio 的 ListObjecsV2 不返回任何结果
- boto3 - 如何在 Boto3 中获取模拟事件
- java - 使用 Bouncy Castle 的 ElGamal 同态乘法