问题
Firstly, I know there are options for using SwiftUI Lists etc... to get similar effects. But I need the automatic scrolling capabilities of a UICollectionView so I'd really like to just implement an "old school" version. I don't even want the compositional layout version ideally.
My current code looks like this:
import SwiftUI
struct CollectionView: UIViewControllerRepresentable {
private var isActive: Binding<Bool>
private let viewController = UIViewController()
private let collectionController: UICollectionView
init(_ isActive: Binding<Bool>) {
self.isActive = isActive
self.collectionController = UICollectionView(frame: CGRect(x: 0, y: 0, width: 100, height: 200), collectionViewLayout: UICollectionViewFlowLayout())
}
func makeUIViewController(context: UIViewControllerRepresentableContext<CollectionView>) -> UIViewController {
return viewController
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<CollectionView>) {
if self.isActive.wrappedValue && collectionController.delegate == nil { // to not show twice
collectionController.delegate = context.coordinator
collectionController.dataSource = context.coordinator
}
}
func makeCoordinator() -> Coordintor {
return Coordintor(owner: self)
}
final class Coordintor: NSObject, UICollectionViewDelegate, UICollectionViewDataSource {
weak var viewController:UIViewController?
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
var cellId = "Cell"
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
return cell
}
// works as delegate
let owner: CollectionView
init(owner: CollectionView) {
self.owner = owner
}
}
}
Unfortunately, all I get is a blank screen in the preview. For now if I can just display a big selection of red squares which I can scroll through and auto scroll to the bottom onAppear, that would be ideal.
Thanks!
回答1:
Here is minimal runnable demo. (Note: Cell have to be registered if all is done programmatically)
class MyCell: UICollectionViewCell {
}
struct CollectionView: UIViewRepresentable {
func makeUIView(context: Context) -> UICollectionView {
let view = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
view.backgroundColor = UIColor.clear
view.dataSource = context.coordinator
view.register(MyCell.self, forCellWithReuseIdentifier: "myCell")
return view
}
func updateUIView(_ uiView: UICollectionView, context: Context) {
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
class Coordinator: NSObject, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
3
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCell", for: indexPath) as! MyCell
cell.backgroundColor = UIColor.red
return cell
}
}
}
struct TestUICollectionView_Previews: PreviewProvider {
static var previews: some View {
CollectionView()
}
}
来源:https://stackoverflow.com/questions/61424672/how-to-present-a-uicollectionview-in-swiftui-with-uiviewcontrollerrepresentable