Ну, для простоты, я хочу знать, как позволить прокрутить UICollectionView вместе с его родительским представлением прокрутки.
Этот SingleMovieView в моем приложении построен в SwiftUI, с представлением прокрутки, содержащим mov ie cover , детали mov ie, такие как жанр, длительность ... и ниже этих двух видов равно createSecCollectionView()
, которые создают UIViewRepresentable для отображения информации, такой как кредиты mov ie, изображения в виде UIKit View.
Проблема, когда я запустил приложение, я обнаружил, что представление UIViewRepresentable не выровнено с этим представлением прокрутки, оно просто go и прокручивается независимо, не выровнено с представлением прокрутки, см. Ниже gif, тогда вы будете знать проблему.
Если это не удалось сделать, я хочу знать, как применить этот внешний вид (вертикальное представление прокрутки включает изображение + текст + много списков прокрутки) в SwiftUI? Как то, что другие виды могут быть использованы.
![enter image description here](https://i.stack.imgur.com/BwkC4.gif)
import SwiftUI
import KingfisherSwiftUI
struct SingleMovieView: View {
var movieId: Int = -1
@ObservedObject var model = MovieListViewModel()
var body: some View {
ScrollView(showsIndicators: false) {
VStack() {
createPosterImage()
MovieDetailView(movie: self.model.movie)
}
if model.secSectionMoviesBundle.isEmpty {
Text("Loading...")
} else {
createSecCollectionView()
}
}.onAppear() {
self.model.getMovieDetail(id: self.movieId)
self.model.getSecSectionMoviesBundle(id: self.movieId)
}
}
fileprivate func createPosterImage() -> some View {
return KFImage(source: .network(model.movie.posterUrl))
.resizable().aspectRatio(contentMode: .fill)
}
fileprivate func createSecCollectionView() -> some View {
return SecMovieCollectionView(allItems: model.secSectionMoviesBundle)
}
}
// Обновление, вот код SecMovieCollectionView
import SwiftUI
struct SecMovieCollectionView: UIViewRepresentable {
var allItems: [SecHomeSection:[MixedMovieBundle]]
//var didSelectItem: ( (_ indexPath: IndexPath) -> () ) = {_ in}
var seeAllforSection: ( (_ section: SecHomeSection)->() ) = {_ in }
func makeUIView(context: Context) -> UICollectionView {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: context.coordinator.createCompositionalLayout())
collectionView.backgroundColor = .clear
collectionView.register(CrewCell.self, forCellWithReuseIdentifier: CrewCell.reuseId)
collectionView.register(CastCell.self, forCellWithReuseIdentifier: CastCell.reuseId)
collectionView.register(ImageCell.self, forCellWithReuseIdentifier: ImageCell.reuseId)
collectionView.register(PopularCell.self, forCellWithReuseIdentifier: PopularCell.reuseId)
collectionView.register(HeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: HeaderView.reuseId)
collectionView.dataSource = context.coordinator
collectionView.delegate = context.coordinator
collectionView.alwaysBounceVertical = true
collectionView.showsVerticalScrollIndicator = false
return collectionView
}
func updateUIView(_ uiView: UICollectionView, context: Context) {
}
func makeCoordinator() -> SecMovieCollectionView.Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UICollectionViewDataSource, UICollectionViewDelegate {
var parent: SecMovieCollectionView
init(_ parent: SecMovieCollectionView) {
self.parent = parent
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
print("all items count: \(parent.allItems.count)")
return parent.allItems.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return parent.allItems[SecHomeSection.allCases[section]]?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
switch indexPath.section {
case 0:
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CrewCell.reuseId, for: indexPath) as? CrewCell {
cell.crew = parent.allItems[.Director]?[indexPath.item] as? CrewViewModel
return cell
}
case 1:
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CastCell.reuseId, for: indexPath) as? CastCell {
cell.cast = parent.allItems[.Cast]?[indexPath.item] as? CastViewModel
return cell
}
case 2:
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ImageCell.reuseId, for: indexPath) as? ImageCell {
cell.image = parent.allItems[.Images]?[indexPath.item] as? ImageViewModel
return cell
}
default:
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PopularCell.reuseId, for: indexPath) as? PopularCell {
cell.movie = parent.allItems[.Recomm]?[indexPath.item] as? MovieViewModel
return cell
}
}
return UICollectionViewCell()
}
// func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// parent.didSelectItem(indexPath)
// }
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: HeaderView.reuseId, for: indexPath) as? HeaderView else {
return UICollectionReusableView()
}
header.name.text = SecHomeSection.allCases[indexPath.section].rawValue
header.onSeeAllClicked = { [weak self] in
print("%%% Click in SecCollectionView %$$$$")
self?.parent.seeAllforSection(SecHomeSection.allCases[indexPath.section])
}
return header
default:
return UICollectionReusableView()
}
}
func createSharedSection() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1))
let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
layoutItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)
let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .fractionalWidth(0.75))
let layoutGroup = NSCollectionLayoutGroup.horizontal(layoutSize: layoutGroupSize, subitems: [layoutItem])
let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
layoutSection.orthogonalScrollingBehavior = .groupPagingCentered
layoutSection.boundarySupplementaryItems = [createSectionHeader()]
return layoutSection
}
func createSectionHeader() -> NSCollectionLayoutBoundarySupplementaryItem {
let layoutSectionHeaderSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(80))
let layoutSectionHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: layoutSectionHeaderSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
return layoutSectionHeader
}
func createCompositionalLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout {[weak self] index, environment in
switch index {
case 0:
return self?.createSharedSection()
case 1:
return self?.createSharedSection()
case 2:
return self?.createSharedSection()
default:
return self?.createSharedSection()
}
}
let config = UICollectionViewCompositionalLayoutConfiguration()
config.interSectionSpacing = 20
layout.configuration = config
return layout
}
}
}