在父容器中滚动时水平滚动集合视图向上移动 [英] Horizontal scrolling collection view shifts up when scrolled in parent container
问题描述
我在父 UIView 中创建了一个水平滚动集合视图,并将其添加到我的 UIViewController 中.但是当我滚动它时,滚动视图会向上移动.
I have created a horizontal scrolling collection view within a parent UIView, which I add in my UIViewController. But the scrolling view shifts up when I scroll on it.
这是容器视图的初始化方式:
This is how the container view is initialized:
override init(frame: CGRect){
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = UICollectionViewFlowLayoutAutomaticSize
layout.estimatedItemSize = CGSize(width: 100, height: 50)
countryCollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
viewTitleLabel = UILabel()
super.init(frame: frame)
setupTableView()
sortedDummyData = dummyData.sorted(by: <)
}
对我的子视图的限制:
NSLayoutConstraint.activate([
viewTitleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
viewTitleLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor),
viewTitleLabel.heightAnchor.constraint(equalToConstant: 30),
viewTitleLabel.widthAnchor.constraint(equalToConstant: 90),
countryCollectionView.leadingAnchor.constraint(equalTo: viewTitleLabel.trailingAnchor, constant: 10),
countryCollectionView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
countryCollectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10),
countryCollectionView.heightAnchor.constraint(equalToConstant: 50)
])
添加到 UIViewContoller 时容器视图的约束:
Constraints on container view when adding to UIViewContoller:
countryCountView.translatesAutoresizingMaskIntoConstraints = false
countryCountView.isUserInteractionEnabled = true
view.addSubview(countryCountView)
NSLayoutConstraint.activate([
countryCountView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
countryCountView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
countryCountView.topAnchor.constraint(equalTo: headerContainer.bottomAnchor),
countryCountView.heightAnchor.constraint(equalToConstant: 60)
])
我的 UICollectionViewCell:
My UICollectionViewCell:
override init(frame: CGRect) {
countryNameLabel = UILabel()
countryUserCountLabel = UILabel()
super.init(frame: frame)
contentView.addSubview(countryNameLabel)
countryNameLabel.translatesAutoresizingMaskIntoConstraints = false
countryNameLabel.font = UIFont.boldSystemFont(ofSize: 13)
countryNameLabel.textColor = .white
contentView.addSubview(countryUserCountLabel)
countryUserCountLabel.translatesAutoresizingMaskIntoConstraints = false
countryUserCountLabel.font = UIFont.systemFont(ofSize: 13)
countryUserCountLabel.textColor = .white
NSLayoutConstraint.activate([
countryNameLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
countryNameLabel.heightAnchor.constraint(equalToConstant: 30),
countryNameLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 5),
countryNameLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5),
// countryNameLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 0),
// countryNameLabel.widthAnchor.constraint(equalToConstant: 20),
countryUserCountLabel.leadingAnchor.constraint(equalTo: countryNameLabel.trailingAnchor, constant: 5),
countryUserCountLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 5),
countryUserCountLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5),
countryUserCountLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -5),
countryUserCountLabel.heightAnchor.constraint(equalToConstant: 30),
// countryUserCountLabel.widthAnchor.constraint(equalToConstant: 40)
])
}
委托方法返回的高度:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 70, height: 40)
// return CGSize.zero
}
滚动前:
滚动后:
设置 collectionView.showsHorizontalScrollIndicator = false
没有帮助.
同时设置 layout.estimatedItemSize = CGSize.zero
可以修复向上移动,但会阻止单元格正确调整大小.
Also setting layout.estimatedItemSize = CGSize.zero
fixes the shifting up but stops the cells from resizing correctly.
推荐答案
由于设置 layout.estimatedItemSize = CGSize.zero
解决了布局移位问题但没有相应地调整单元格的大小,我猜您可能已经硬编码了集合视图的每个单元格中使用的标签的宽度限制.(就像 viewTitleLabel
代码中的约束一样)
Since setting layout.estimatedItemSize = CGSize.zero
solves the layout shift issue but does not resize the cells accordingly, I'm guessing a possibility where you might have hardcoded the width constraint for the label used in each cell of your collection view. (Like the constraints from your code for viewTitleLabel
)
假设是这种情况并且您希望自动调整大小,您可以尝试删除硬编码的宽度限制.(如果有)
Assuming that this is the case and you want auto-resizing to take place, you can try removing the hardcoded width constraints. (If any)
为了发挥自动布局的魔力,UILabel
通常只需要 X 和 Y 位置约束,除非您需要严格控制边界
For auto-layout to do its magic, only the X and Y position constraints are usually needed for UILabel
unless you need strict control over the boundaries
问题似乎出在单元格约束的设置方式上.这是细分:
The problem seems to be with the way the cell constraints are set up. Here's the breakdown:
升档是因为:
单元格最初加载时使用集合视图的高度,即:50
The cells are initially loaded with your collection view's height i.e: 50
由于您设置了 layout.itemSize = UICollectionViewFlowLayout.automaticSize
,流布局会覆盖默认高度 50,并根据其子视图约束设置设置单元格高度.
Since you've set layout.itemSize = UICollectionViewFlowLayout.automaticSize
, the flow layout overrides the default height of 50 and sets the cell height according to its subview constraints setup.
您已指定标签的 heightAnchor
为 30,topAnchor
为 5,bottomAnchor
为 -5计算自动布局时单元格的总高度为 40
You've specified the label's heightAnchor
to be 30, topAnchor
to be 5, and the bottomAnchor
to -5 making the cell's overall height to be 40 when calculating for autolayout
这个从 50 到 40 的高度切换会导致您的升档".问题.
This height switch from 50 to 40 causes your "shift-up" issue.
要解决这个问题:
您可以将标签的
heightAnchor
更改为 50 以匹配集合视图的高度,设置其centerYAnchor
并保持您的layout.itemSize =UICollectionViewFlowLayout.automaticSize
You can change the label's
heightAnchor
to be 50 to match with the collection view's height, set itscenterYAnchor
and maintain yourlayout.itemSize = UICollectionViewFlowLayout.automaticSize
(OR)
设置标签的centerYAnchor
,手动指定layout.itemSize
,高度为50
Set the label's centerYAnchor
and manually specify layout.itemSize
with a height of 50
这篇关于在父容器中滚动时水平滚动集合视图向上移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!