首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当视图出现时,如何滚动到某个点? UIViewRepresentable UICollectionView?

当视图出现时,如何滚动到某个点? UIViewRepresentable UICollectionView?
EN

Stack Overflow用户
提问于 2022-06-11 00:51:24
回答 2查看 116关注 0票数 0

我有下面的代码,但是我不知道将它放在我的UIViewRepresntable中的位置。有什么建议吗?

代码语言:javascript
复制
    let scrollTo = IndexPath(row: 25, section: 0)
    view.scrollToItem(at: scrollTo, at: .top, animated: false)


struct CollectionViewRepresentable: UIViewRepresentable {
    
    @StateObject var vm = CollectionViewModel()

    let view = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewCompositionalLayout.list(using: UICollectionLayoutListConfiguration(appearance: .plain)))
    
    func makeUIView(context: Context) -> UICollectionView {

        view.backgroundColor = UIColor.clear
        view.dataSource = context.coordinator
        view.delegate = context.coordinator
        view.register(ListCell.self, forCellWithReuseIdentifier: "listCell")
        return view
    }

    func updateUIView(_ uiView: UICollectionView, context: Context) {
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UICollectionViewDelegate, UICollectionViewDataSource {
        private var parent: CollectionViewRepresentable

        init(_ collectionViewRepresentable: CollectionViewRepresentable) {
            self.parent = collectionViewRepresentable
        }

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

        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! ListCell
            let item = parent.vm.items[indexPath.row]
            cell.item = item
            return cell
        }
    }
}

当视图出现时,我需要滚动到那个位置。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-06-11 04:55:26

您可以使用ViewControllerRepresentable,并利用视图控制器可以覆盖viewWillAppear/viewDidAppear方法这一事实,在该方法中,可以编写滚动代码。

为此,子类UICollectionViewController,并将所有集合视图相关逻辑移到:

代码语言:javascript
复制
class MyCollectionViewController: UICollectionViewController {
    var vm = CollectionViewModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.backgroundColor = UIColor.clear
        collectionView.register(ListCell.self, forCellWithReuseIdentifier: "listCell")
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        let scrollTo = IndexPath(row: 25, section: 0)
        collectionView.scrollToItem(at: scrollTo, at: .top, animated: false)
    }
    
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return vm.items.count
    }
    
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! ListCell
        let item = vm.items[indexPath.row]
        cell.item = item
        return cell
    }
}

考虑到上述情况,SwiftUI代码简化为如下所示:

代码语言:javascript
复制
struct CollectionViewRepresentable: UIViewControllerRepresentable {
    
    func makeUIViewController(context: Context) -> MyCollectionViewController {
        .init(collectionViewLayout: UICollectionViewFlowLayout())
    }
    
    func updateUIViewController(_ vc: MyCollectionViewController, context: Context) {
    }
}
票数 1
EN

Stack Overflow用户

发布于 2022-06-11 04:20:25

场景还不完全清楚,但可以在可表示的内部使用外部StateBinding,并通过调用updateUIView进行更改。

所以一个可能的解决办法是

代码语言:javascript
复制
@State private var scrollTo = IndexPath(row: 25, section: 0) // << in parent !! 

// ...

struct CollectionViewRepresentable: UIViewRepresentable {
    @Binding var scrollTo: IndexPath                       // << 1) !!
    @StateObject private var vm = CollectionViewModel()

    func makeUIView(context: Context) -> UICollectionView {
        let view = UICollectionView(...)    // << move creation here !!
        // ... other code
        return view
    }

    func updateUIView(_ uiView: UICollectionView, context: Context) {
       // called at start and when binding updated
       uiView.scrollToItem(at: scrollTo, at: .top, animated: false)  // << 2) !!
    }
// ... other code
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72580985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档