我做了一个水平滚动的UICollectionView,我希望中间的单元格具有白色字体,而其余单元格是黑色。

如果我只使用scrollViewDidEndDecelerating,则中间单元格的突出显示似乎比我同时使用scrollViewWillBeginDecelerating和scrollViewDidEndDecelerating突出显示中间单元的跳跃更多。这是不好的做法吗?

extension CurrencySelectorTableViewCell: UIScrollViewDelegate{
    func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
        self.findCenterIndex()
    }

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        self.findCenterIndex()
    }
}


这段代码仍然没有像我想要的那样完美地进行动画处理,因此我对如何使此滚动机制尽可能平滑的建议持开放态度。

因此,当UICollectionView开始滚动时,将触发此函数:

func findCenterIndex() {
    let center = self.convert(self.collectionView.center, to: self.collectionView)
    let index = collectionView!.indexPathForItem(at: center)

    if let selectedIndex = index {
        self.selectedCell = selectedIndex.item
        self.collectionView.reloadData()
    }
}


重新加载UICollectionView后,位于中间的单元格中的标签将与其余单元格看起来不同:

func collectionView(_ collectionView: UICollectionView,
                             cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CurrencySelectorCollectionViewCell", for: indexPath) as! CurrencySelectorCollectionViewCell

    if (indexPath.item == self.selectedCell) {
        cell.currencyLabel.textColor = UIColor.white
        cell.currencyLabel.font = cell.currencyLabel.font.withSize(22)
    } else {
        cell.currencyLabel.textColor = UIColor.black
        cell.currencyLabel.font = cell.currencyLabel.font.withSize(15)
    }

    cell.currencyLabel.text = currencies[indexPath.item]

    return cell
}


现在它会跳一点,因为它只会在滚动刚刚开始或刚刚停止时才更改标签。我希望对UITextLabel的这种影响在整个滚动过程中持续发生。

最佳答案

在触发新动画之前,尝试添加UILabel层的removeAllAnimations()

[view.layer removeAllAnimations];


编辑:

根据问题中的编辑,您没有运行任何动画。您正在reloadData上调用UICollectionView,这确实是一种不好的做法。

您应该要么简单:

1 :(错误选项)

仅使用performBatchUpdates(_:completion:)重新加载单元

2:不错的选择

使用cellForItem(at:)作为单元findCenterIndex中的变量访问单元,只需对标签进行更新即可。

您也可以通过获取visibleCells数组来取消选择其他单元格,只需按照上述相同的方式进行操作,但是您将触发“取消选择”代码。您实际上可以在运行选择代码之前执行此操作。或只需在可见的单元格上运行一个for循环并在循环中“取消选择”它们,然后在CGPoint中心中选择一个,即可完成一项操作。

这样,您甚至不必重新加载UICollectionView,这是最佳实践。而且您还可以避免闪烁和动画。

关于ios - 滚动UICollectionViews的不良做法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42275027/

10-12 14:42
查看更多