ios - Swift - 滚动集合视图时标签移动到单元格的左上角
问题描述
每个单元格都有一个带有标签的标题,并且它应该位于单元格的中心。当视图控制器第一次出现时,每个标签都正确显示,但是当我向下滚动第一个单元格时,将标签移动到左上角,当我向上滚动最后一个单元格时,标签也会移动。如何将每个标签设置为固定在其初始位置?
class TopicsVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UISearchBarDelegate {
override func viewDidLoad() {
self.filteredNames = self.names
self.collectionView.register(SearchCollectionViewCell.self, forCellWithReuseIdentifier: "SearchCollectionViewCell.identifier")
self.collectionView.register(TextCollectionViewCell.self, forCellWithReuseIdentifier: "TextCollectionViewCell.identifier")
if let collectionViewLayout = self.collectionView.collectionViewLayout as? RSKCollectionViewRetractableFirstItemLayout {
collectionViewLayout.firstItemRetractableAreaInset = UIEdgeInsets(top: 8.0, left: 0.0, bottom: 8.0, right: 0.0)
}
}
fileprivate let names = ["F", "N", "S", "M", "R", "T", "A", "M", "T", "F"]
fileprivate let images = ["f.png", "n.png", "s.png", "m.png", "r.png", "t.png", "a.png","m.png","t.png","f.png"]
// MARK: - Layout
internal override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard self.readyForPresentation == false else {
return
}
self.readyForPresentation = true
let searchItemIndexPath = IndexPath(item: 0, section: 0)
self.collectionView.contentOffset = CGPoint(x: 0.0, y: self.collectionView(self.collectionView, layout: self.collectionView.collectionViewLayout, sizeForItemAt: searchItemIndexPath).height)
}
// MARK: - UICollectionViewDataSource
internal func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
switch indexPath.section {
case 0:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchCollectionViewCell.identifier", for: indexPath) as! SearchCollectionViewCell
cell.searchBar.delegate = self
cell.searchBar.searchBarStyle = .minimal
cell.searchBar.placeholder = "Search a topic"
return cell
case 1:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TextCollectionViewCell.identifier", for: indexPath) as! TextCollectionViewCell
let name = self.filteredNames[indexPath.item]
cell.colorView.layer.cornerRadius = 10.0
cell.colorView.layer.masksToBounds = true
//cell.colorView.backgroundColor = self.colors[name]
cell.colorView.backgroundColor = UIColor(patternImage: UIImage(named: images[indexPath.row])!)
cell.colorView.layer.contents = UIImage.init(named:images[indexPath.row])!.cgImage
cell.label.textColor = UIColor.white
cell.label.font = UIFont(name:"HelveticaNeue-Bold", size: 24.0)
cell.label.sizeToFit()
cell.label.numberOfLines = 2
cell.label.textAlignment = .center
cell.label.text = name
return cell
default:
assert(false)
}
}
internal func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
switch section {
case 0:
return 1
case 1:
return self.filteredNames.count
default:
assert(false)
}
}
internal func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
// MARK: - UICollectionViewDelegateFlowLayout
internal func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
switch section {
case 0:
return UIEdgeInsets.zero
case 1:
return UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0)
default:
assert(false)
}
}
internal func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10.0
}
internal func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 10.0
}
internal func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
switch indexPath.section {
case 0:
let itemWidth = collectionView.frame.width
let itemHeight: CGFloat = 150.0
return CGSize(width: itemWidth, height: itemHeight)
case 1:
let numberOfItemsInLine: CGFloat = 2
let inset = self.collectionView(collectionView, layout: collectionViewLayout, insetForSectionAt: indexPath.section)
let minimumInteritemSpacing = self.collectionView(collectionView, layout: collectionViewLayout, minimumInteritemSpacingForSectionAt: indexPath.section)
let itemWidth = (collectionView.frame.width - inset.left - inset.right - minimumInteritemSpacing * (numberOfItemsInLine - 1)) / numberOfItemsInLine
let itemHeight = itemWidth
return CGSize(width: itemWidth, height: itemHeight)
default:
assert(false)
}
}
// MARK: - UIScrollViewDelegate
internal func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
guard scrollView === self.collectionView else {
return
}
let indexPath = IndexPath(item: 0, section: 0)
guard let cell = self.collectionView.cellForItem(at: indexPath) as? SearchCollectionViewCell else {
return
}
guard cell.searchBar.isFirstResponder else {
return
}
cell.searchBar.resignFirstResponder()
}
// MARK: - UISearchBarDelegate
internal func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
let oldFilteredNames = self.filteredNames!
if searchText.isEmpty {
self.filteredNames = self.names
}
else {
self.filteredNames = self.names.filter({ (name) -> Bool in
return name.hasPrefix(searchText)
})
}
self.collectionView.performBatchUpdates({
for (oldIndex, oldName) in oldFilteredNames.enumerated() {
if self.filteredNames.contains(oldName) == false {
let indexPath = IndexPath(item: oldIndex, section: 1)
self.collectionView.deleteItems(at: [indexPath])
}
}
for (index, name) in self.filteredNames.enumerated() {
if oldFilteredNames.contains(name) == false {
let indexPath = IndexPath(item: index, section: 1)
self.collectionView.insertItems(at: [indexPath])
}
}
}, completion: nil)
}
解决方案
可能是 code:cell.label.sizeToFit()
在您的实现中collectionView(_:, cellForItemAt:)
导致了问题。我建议删除该行。
推理:如果您已经在 Interface Builder 中设置了标签以使单元格中的文本居中,则无需在此处更新标签大小。调整大小以适应可能会导致标签缩小,从而可能导致您所描述的似乎向左上角移动的行为。
(更糟糕的是,上面代码中的调用sizeToFit()
发生在您实际为单元格设置新文本之前,因此其结果将基于单元格中在重用之前的文本。)
推荐阅读
- haskell - Haskell:比较字符
- javascript - Node.js xml2js - 创建站点地图属性时被忽略
- javascript - 使用 DynamoDB.DocumentClient 成功进行事务处理后,ItemCollectionMetrics 为空
- r - 我如何将此数组划分为 R 中的列
- laravel - 表之间的关系不起作用
- azure - Azure SQL server 实例连接字符串问题
- javascript - Javascript/jQuery - 对于所有多维键的每个数组迭代
- python - 根据类别过滤帖子
- sql-server - 有一个字段就是一个时间,需要找那些HH:MM AM/HH:MM PM格式之外的
- java - 如何使用java将对象插入正确的位置?