Post not yet marked as solved
Post marked as unsolved with 3 replies, 4,754 views
I have searced far and wide and finally compared Apples WWDC example code. It seems evident that when adding UIScrollViewDelegate methods to the "Orthogonal Section Behaviours" example code, the delegates only get fired when scrolling vertically.Is this an expected behaviour and UIScrollViewDelegate is not supported horizontally by CompositionalLayout or is it something that will be addressed?/*
See LICENSE folder for this sample’s licensing information.
Abstract:
Orthogonal scrolling section behaviors example
*/
import UIKit
class OrthogonalScrollBehaviorViewController: UIViewController {
static let headerElementKind = "header-element-kind"
enum SectionKind: Int, CaseIterable {
case continuous, continuousGroupLeadingBoundary, paging, groupPaging, groupPagingCentered, none
func orthogonalScrollingBehavior() -> UICollectionLayoutSectionOrthogonalScrollingBehavior {
switch self {
case .none:
return UICollectionLayoutSectionOrthogonalScrollingBehavior.none
case .continuous:
return UICollectionLayoutSectionOrthogonalScrollingBehavior.continuous
case .continuousGroupLeadingBoundary:
return UICollectionLayoutSectionOrthogonalScrollingBehavior.continuousGroupLeadingBoundary
case .paging:
return UICollectionLayoutSectionOrthogonalScrollingBehavior.paging
case .groupPaging:
return UICollectionLayoutSectionOrthogonalScrollingBehavior.groupPaging
case .groupPagingCentered:
return UICollectionLayoutSectionOrthogonalScrollingBehavior.groupPagingCentered
}
}
}
var dataSource: UICollectionViewDiffableDataSource<Int, Int>! = nil
var collectionView: UICollectionView! = nil
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Orthogonal Section Behaviors"
configureHierarchy()
configureDataSource()
}
}
extension OrthogonalScrollBehaviorViewController {
// +-----------------------------------------------------+
// | +---------------------------------+ +-----------+ |
// | | | | | |
// | | | | | |
// | | | | 1 | |
// | | | | | |
// | | | | | |
// | | | +-----------+ |
// | | 0 | |
// | | | +-----------+ |
// | | | | | |
// | | | | | |
// | | | | 2 | |
// | | | | | |
// | | | | | |
// | +---------------------------------+ +-----------+ |
// +-----------------------------------------------------+
func createLayout() -> UICollectionViewLayout {
let config = UICollectionViewCompositionalLayoutConfiguration()
config.interSectionSpacing = 20
let layout = UICollectionViewCompositionalLayout(sectionProvider: {
(sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
guard let sectionKind = SectionKind(rawValue: sectionIndex) else { fatalError("unknown section kind") }
let leadingItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(0.7), heightDimension: .fractionalHeight(1.0)))
leadingItem.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
let trailingItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(0.3)))
trailingItem.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
let trailingGroup = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(0.3), heightDimension: .fractionalHeight(1.0)),
subitem: trailingItem,
count: 2)
let orthogonallyScrolls = sectionKind.orthogonalScrollingBehavior() != .none
let containerGroupFractionalWidth = orthogonallyScrolls ? CGFloat(0.85) : CGFloat(1.0)
let containerGroup = NSCollectionLayoutGroup.horizontal(
layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(containerGroupFractionalWidth),
heightDimension: .fractionalHeight(0.4)),
subitems: [leadingItem, trailingGroup])
let section = NSCollectionLayoutSection(group: containerGroup)
section.orthogonalScrollingBehavior = sectionKind.orthogonalScrollingBehavior()
let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(44)),
elementKind: OrthogonalScrollBehaviorViewController.headerElementKind,
alignment: .top)
section.boundarySupplementaryItems = [sectionHeader]
return section
}, configuration: config)
return layout
}
}
extension OrthogonalScrollBehaviorViewController {
func configureHierarchy() {
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout())
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
collectionView.backgroundColor = .systemBackground
collectionView.register(TextCell.self, forCellWithReuseIdentifier: TextCell.reuseIdentifier)
collectionView.register(ListCell.self, forCellWithReuseIdentifier: ListCell.reuseIdentifier)
collectionView.register(
TitleSupplementaryView.self,
forSupplementaryViewOfKind: OrthogonalScrollBehaviorViewController.headerElementKind,
withReuseIdentifier: TitleSupplementaryView.reuseIdentifier)
view.addSubview(collectionView)
collectionView.delegate = self
}
func configureDataSource() {
dataSource = UICollectionViewDiffableDataSource<Int, Int>(collectionView: collectionView) {
(collectionView: UICollectionView, indexPath: IndexPath, identifier: Int) -> UICollectionViewCell? in
// Get a cell of the desired kind.
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: TextCell.reuseIdentifier, for: indexPath) as? TextCell
else { fatalError("Cannot create new cell") }
// Populate the cell with our item description.
cell.label.text = "\(indexPath.section), \(indexPath.item)"
cell.contentView.backgroundColor = .cornflowerBlue
cell.contentView.layer.borderColor = UIColor.black.cgColor
cell.contentView.layer.borderWidth = 1
cell.contentView.layer.cornerRadius = 8
cell.label.textAlignment = .center
cell.label.font = UIFont.preferredFont(forTextStyle: .title1)
// Return the cell.
return cell
}
dataSource.supplementaryViewProvider = {
(collectionView: UICollectionView, kind: String, indexPath: IndexPath) -> UICollectionReusableView? in
guard let sectionKind = SectionKind(rawValue: indexPath.section)
else { fatalError("Unknown section kind") }
// Get a supplementary view of the desired kind.
if let header = collectionView.dequeueReusableSupplementaryView(
ofKind: kind,
withReuseIdentifier: TitleSupplementaryView.reuseIdentifier,
for: indexPath) as? TitleSupplementaryView {
// Populate the view with our section's description.
header.label.text = "." + String(describing: sectionKind)
// Return the view.
return header
} else {
fatalError("Cannot create new header")
}
}
// initial data
var snapshot = NSDiffableDataSourceSnapshot<Int, Int>()
var identifierOffset = 0
let itemsPerSection = 18
SectionKind.allCases.forEach {
snapshot.appendSections([$0.rawValue])
let maxIdentifier = identifierOffset + itemsPerSection
snapshot.appendItems(Array(identifierOffset..<maxIdentifier))
identifierOffset += itemsPerSection
}
dataSource.apply(snapshot, animatingDifferences: false)
}
}
extension OrthogonalScrollBehaviorViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("ScrollView decel rate: \(scrollView.decelerationRate)")
print("DidIt")
print("DidIt")
print("DidIt")
}
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("Begin")
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("End")
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
print("END")
}
}