繁体   English   中英

改善复杂集合视图构造中的滚动

Improving scrolling in complex collection views construct

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我正在研究一个灵活的表单组件,该组件基本上由具有集合视图的UIViewController组成,该组件可以具有该类的无限嵌套的视图控制器。 在当前状态下,它或多或少都可以正常工作,但是不幸的是滚动不稳定,而且我还没有找到解决该问题的方法。 也许你们当中有人想出一个好的解决方案。 我还尝试过缓存视图控制器,这有助于实现平滑的滚动,但是不幸的是,有了该解决方案,我开始出现显示问题。 有时,单元格的内容只是消失了,我无法弄清其原因。

这是完整项目的链接: https : //d.pr/f/0ij57m

该项目的主要部分基本上是这个FlexibleViewController(通过情节提要设计)

class FlexibleViewController: UIViewController {

    var dataForDatasource = Array<Component>()
    var datasource: UICollectionViewDataSource?

    @IBOutlet var collectionView: UICollectionView! {
        didSet {
            let datasource = MyDatasource(data: dataForDatasource, parentController: self)
            self.datasource = datasource
            self.collectionView.dataSource = datasource
            self.collectionView.delegate = datasource
        }
    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        self.view.setNeedsLayout()
        self.collectionView?.collectionViewLayout.invalidateLayout()
    }

    func invalidateLayout() {
        self.collectionView.collectionViewLayout.invalidateLayout()
        if let controller = self.parent as? FlexibleViewController {
            controller.invalidateLayout()
        }
    }
}

而这个数据源:

    class MyDatasource: NSObject, UICollectionViewDataSource, UICollectionViewDelegate {

    weak var parentController: UIViewController!
    var components: Array<Component>!

    init(data: Array<Component>, parentController: UIViewController) {
        self.components = data
        self.parentController = parentController
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return components.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let component = components[indexPath.row]

        var cell: UICollectionViewCell?
        if component.subComponents.count > 0 {
            let collectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collection", for: indexPath) as! TestCell

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let vs = storyboard.instantiateViewController(withIdentifier: "flexi") as! FlexibleViewController
            vs.dataForDatasource = component.subComponents

            parentController.addChild(vs)
            collectionCell.addSubview(vs.view)
            vs.collectionView.backgroundColor = component.backgroundColor
            vs.didMove(toParent: parentController)
            collectionCell.controller = vs

            cell = collectionCell
        } else {
            cell = collectionView.dequeueReusableCell(withReuseIdentifier: "default", for: indexPath)
            cell!.backgroundColor = component.backgroundColor
        }

        return cell!
    }
}

extension MyDatasource: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        var sizeForItem: CGSize
        let component = components[indexPath.row]
        var width = Int(collectionView.frame.size.width)
        if component.width != -1 && component.width < width {
            width = component.width
        }

        var height: Int = 50
        if component.subComponents.count > 0 {
            let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: width, height: height), collectionViewLayout: UICollectionViewFlowLayout())
            let datasource = MyDatasource(data: component.subComponents, parentController: UIViewController())
            collectionView.dataSource = datasource
            collectionView.delegate = datasource
            collectionView.reloadData()
            height = Int(collectionView.collectionViewLayout.collectionViewContentSize.height)
            sizeForItem = CGSize(width: width, height: height)
        } else {
            sizeForItem = CGSize(width: width, height: height)
        }
        return sizeForItem

    }
}

如您所见,当该组件具有多个组件时,将通过情节提要实例化具有集合视图的新控制器,这可能并不理想(尽管并不像我预期的那样昂贵)。 我试图重新初始化viewDidLoad中的所有控制器,但是就像我在介绍中所说的那样,该解决方案遇到显示问题。

该单元格非常简单,看起来像这样:

class TestCell: UICollectionViewCell {
    var controller: UIViewController?

    override func prepareForReuse() {
        super.prepareForReuse()
        controller?.willMove(toParent: nil)
        controller?.removeFromParent()
        controller?.view.removeFromSuperview()
    }
}

组件类如下所示:

class Component {
    var generatedId = NSUUID().uuidString
    var identifier: String?
    var subComponents = Array<Component>()
    var width: Int! = -1
    var type: String! = "default"
    var backgroundColor: UIColor! = .white
    var isOpen: Bool = false
}

在此先感谢您的帮助! :-)

1 个回复

您应该看看Apple关于预取集合视图数据的出色文档。

它包含一个(Swift)示例项目,并大量使用OperationQueueNSCache

基本思想是“预取”并缓存下一个项目,然后显示它们以进行平滑滚动。 向后滚动时,将从缓存中获取项目。

1 滚动垂直的集合视图堆栈

在视图控制器上,我有一堆集合视图,每个视图都水平滚动。 我可以很好地滚动我的收藏夹视图,但是我不能进入最底部的收藏夹视图,因为屏幕不能垂直滚动。 我要怎么做才能使整个屏幕垂直滚动? 我尝试在这些集合视图后面添加滚动视图,但这似乎无济于事。 我需要将collectionview放 ...

2 改善情结

我很困惑。 如果我必须证明, 现在,在此,如果我计算极限, 通过这个我可以说这确实属于big-o(4n)。 Be对于任何n值都不正确。 这是正确的证明方式吗? ...

3 MVC视图中的复杂网址-谁负责构造它们?

可以说我需要创建一个搜索页面。 在该页面上有: 具有许多搜索参数(param1,param2,...,paramN)的复杂搜索过滤器 结果项列表 传呼机 布局开关链接(列表或表视图) 我将动作从一个视图模型传递到一个视图,其中包含有关搜索参数(来自ur ...

4 滚动视图以及集合视图单元格

在我的视图控制器上,我在视图控制器顶部的2个视图下面有1个collectionview,我根据视图的大小设置了集合视图的高度,因此collectionview足够大,不需要滚动。 所有3个视图都在滚动视图内部,因此我可以无缝滚动视图和集合单元。 这感觉效率很低,但是我想不出另一种在视图和co ...

5 在tableview行中同步水平滚动集合视图

我正在尝试在表视图中同步所有集合视图中的滚动(请参阅下面的图像链接): 示例图片: http : //postimg.org/image/dduhr89e5/ 我能够找到的示例解释了如何通过识别每个滚动视图来同步两个单独的滚动视图。 但是,我不确定如何在表视图中识别每个集合视图。 ...

6 在Swift中将滚动与两个集合视图同步?

有没有一种做法可以滚动带有单元格的集合视图,并根据其内容偏移量来滚动另一个集合视图? 我有一个具有两个单元格并水平滚动的主集合视图。 然后,我有了第二个集合视图,其中的单元格可以垂直滚动。 发生的情况是,当我向上滚动然后水平滚动到第二个垂直简历时,它与第一个垂直简历没有同步。 我 ...

7 视图中的垂直和水平滚动集合视图

我有几个水平滚动集合视图和一个垂直滚动集合视图,它们被添加到同一视图中。 这些集合视图是这样重叠的。 如果您要触摸水平滚动收集视图,我仍然希望能够滚动垂直滚动收集视图,反之亦然。 那有可能吗? ...

8 改善对话框滚动

我创建了一个对话框,该对话框使用position:fixed , overflow:auto和display:table的组合与屏幕中间对齐,如下所示: .dialog { position: fixed; left: 0; right: 0; top: 0; bott ...

9 改善UITableView滚动

我卡住了一些UITableView滚动问题。 我知道这个问题有很多,还有一些解决方案。 但是,从技术角度来看(如何做到这一点),我找不到解决方案。 好吧,在我的情况下,滚动不是很平滑,因为其中包含图像。 从文件加载它需要很多时间。 我也创建自定义UITableViewCell并使用 ...

10 代码改进:视图列表

我有以下代码: 是否有更好的解决方案将Views初始化为数组? 我试过像这样的ArrayList: 也许这可能比上面的解决方案好一点,但是它不起作用。 还是有可能使用循环? 那么我认为ID必须是可迭代的,但是怎么可能呢? 任何帮助或要学习的新信息将不胜感激。 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM