Swift - 滚动集合视图时,Label移动到单元格的左上角

问题描述 投票:0回答:1

每个单元格都有一个带标签的标题,它应该以单元格为中心。当视图控制器首次出现时,每个标签都正确显示,但是当我向下滚动时,第一个单元格将标签移动到左上角,当我向上滚动时,最后一个单元格也会移动标签。如何将每个标签设置为保持固定在其初始位置?

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)
}
ios swift scroll uicollectionview cell
1个回答
1
投票

你的cell.label.sizeToFit()实现中的代码:collectionView(_:, cellForItemAt:)可能会导致问题。我建议删除该行。

推理:如果您已在Interface Builder中设置标签以将文本居中放置在单元格中,则无需在此处更新标签大小。调整大小以适应可能导致标签缩小,可能导致您所描述的行为似乎向左上方移动。

(更糟糕的是,上面代码中对sizeToFit()的调用发生在实际为单元格设置新文本之前,因此其结果将基于单元格在重用之前的文本。)

© www.soinside.com 2019 - 2024. All rights reserved.