I have the following code, but I am not sure where to place it in my UIViewRepresntable. Any suggestions?
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
}
}
}
I need to scroll to that position when the view appears.
You could use ViewControllerRepresentable
and take advantage of the fact that view controllers can override the viewWillAppear
/viewDidAppear
methods where you can write the code that scrolls.
For this, subclass UICollectionViewController
, and move all the collection view related logic there:
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
}
}
With the above in mind, the SwiftUI code simplifies to something like this:
struct CollectionViewRepresentable: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> MyCollectionViewController {
.init(collectionViewLayout: UICollectionViewFlowLayout())
}
func updateUIViewController(_ vc: MyCollectionViewController, context: Context) {
}
}