RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1225176
Accepted
Atlantis
Atlantis
Asked:2021-12-29 13:24:30 +0000 UTC2021-12-29 13:24:30 +0000 UTC 2021-12-29 13:24:30 +0000 UTC

UICollectionView 项目滚动速度

  • 772

我有一个启用分页的 UICollectionView,并且每个屏幕有一个项目居中。我以编程方式滚动浏览特定事件的单元格。

你能告诉我我是否能以某种方式控制细胞的速度吗?

例如。

我需要当前单元格在 500 毫秒内离开屏幕。下一个等待了 200 毫秒,并在 300 毫秒内出现在它的位置。

ios
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Andrew
    2021-12-29T16:07:28Z2021-12-29T16:07:28Z

    您可以尝试这样做:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.collectionView.decelerationRate = UIScrollView.DecelerationRate.fast
    }
    

    这是有关该主题和文档的文章

    • 0
  2. Best Answer
    VAndrJ
    2022-01-06T20:01:05Z2022-01-06T20:01:05Z

    从你能想到的一件简单的事情——你需要一个定制的UICollectionViewFlowLayout。

    主要思想是在所需事件的元素之间添加“间隙”,移动第一个,然后滚动到下一个。结果的粗略单向示例:

    在此处输入图像描述

    // MARK: - Вызов события проскроллить до следующего элемента
    #warning("только для примера, не повторять в реальной жизни")
    let jellyLayout = collectionView.collectionViewLayout as! JellyFlowLayout
    let indexPath = collectionView.indexPathForItem(at: view.convert(CGPoint(x: UIScreen.main.bounds.width / 2, y: 200), to: collectionView))!
    // MARK: - ну как-то так.
    jellyLayout.addPadding(at: indexPath)
    UIView.animate(withDuration: jellyLayout.moveOutAnimationDuration) { [self] in
        // MARK: - А ещё нужно обработать если не идеально расположена ячейка или там paging сделать и т.п.
        collectionView.contentOffset = CGPoint(x: collectionView.contentOffset.x + jellyLayout.itemSize.width + jellyLayout.cellPadding, y: collectionView.contentOffset.y)
    }
    ...
    // MARK: - Набросок этого кастомного UICollectionViewFlowLayout. 
    class JellyFlowLayout: UICollectionViewFlowLayout {
        private var attributesCache = [UICollectionViewLayoutAttributes]()
        private var indexPathWithPadding: IndexPath? = nil
        var cellPadding: CGFloat = 8
        var contentHeight: CGFloat = 300
        var contentWidth: CGFloat = 0
        override var collectionViewContentSize: CGSize {
            return CGSize(width: contentWidth, height: contentHeight)
        }
        // MARK: - За сколько первая ячейка "уедет"
        var moveOutAnimationDuration: TimeInterval = 0.5 * 3
        // MARK: - За сколько вторая ячейка "подтянется"
        var moveInAnimationDuration: TimeInterval = 0.3 * 3
        
        func addPadding(at indexPath: IndexPath) {
            indexPathWithPadding = indexPath
            attributesCache = []
            contentWidth = 0
            UIView.animate(withDuration: moveOutAnimationDuration) { [self] in
                collectionView?.performBatchUpdates({
                    invalidateLayout()
                    collectionView?.layoutIfNeeded()
                }, completion: nil)
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + moveOutAnimationDuration - moveInAnimationDuration) { [self] in
                removePadding()
            }
        }
    
        func removePadding() {
            indexPathWithPadding = nil
            attributesCache = []
            contentWidth = 0
            UIView.animate(withDuration: moveInAnimationDuration) { [self] in
                // MARK: - Нормально двигает только с performBatchUpdates, может есть и другой вариант
                collectionView?.performBatchUpdates({
                    invalidateLayout()
                    collectionView?.layoutIfNeeded()
                }, completion: nil)
            }
        }
        
        override func prepare() {
            // MARK: - Здесь пересчитываем для нужных вжух. Если посчитано - игнорим.
            guard let collectionView = collectionView, attributesCache.isEmpty else {
                return
            }
            // MARK: - Тут жестко по данным для примера, одна секция с элементами
            for item in 0..<collectionView.numberOfItems(inSection: 0) {
                let indexPath = IndexPath(item: item, section: 0)
                let frame = CGRect(x: contentWidth, y: 0, width: itemSize.width, height: contentHeight)
                contentWidth += frame.width + cellPadding
                // MARK: - Вот этим добиваемся эффекта вжух за счет добавления "зазора" на ширину ячейки
                if indexPath == indexPathWithPadding {
                    contentWidth += itemSize.width
                }
                let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
                attributes.frame = frame
                attributesCache.append(attributes)
            }
        }
        
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            var visibleLayoutAttributes = [UICollectionViewLayoutAttributes]()
            for attributes in attributesCache {
                if attributes.frame.intersects(rect) {
                    visibleLayoutAttributes.append(attributes)
                }
            }
            return visibleLayoutAttributes
        }
        
        override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
            return attributesCache[indexPath.item]
        }
    }
    
    • 0

相关问题

  • UIImageView 相对于 superview 缩放后的位置

  • 在密码中授权 type basic 时,符号#swift 4 被错误传输到服务器

  • 将 AppDelegate.h 添加到项目中

  • 调用共享表时出错

  • 接近传感器模拟

  • 帮助 ios 应用程序架构 (MVP)

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5