У меня есть UICollectionViewCompositionalLayout. Мое приложение похоже на App Store. В реальном App Store, когда я хочу прокрутить «UICollectionViewCell» с помощью каталога приложений и мой палец случайно нажимает на значок приложения (кнопку действия), я могу без проблем прокручивать дальше. Но в моем приложении, если я сделаю то же самое, я не смогу продолжить прокрутку, потому что срабатывает действие кнопки. Как это исправить?
Видео, демонстрирующее проблему:
Реальное поведение App Store
Мое приложение поведение Код ячейки:
class AppsViewController: UIViewController {
let sections = Bundle.main.decode([Section].self, from: "appstore.json")
var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource?
override func viewDidLoad() {
super.viewDidLoad()
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createCompositionalLayout())
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
collectionView.backgroundColor = .systemBackground
view.addSubview(collectionView)
collectionView.register(SectionHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: SectionHeader.reuseIdentifier)
collectionView.register(FeaturedCell.self, forCellWithReuseIdentifier: FeaturedCell.reuseIdentifier)
collectionView.register(MediumTableCell.self, forCellWithReuseIdentifier: MediumTableCell.reuseIdentifier)
collectionView.register(SmallTableCell.self, forCellWithReuseIdentifier: SmallTableCell.reuseIdentifier)
createDataSource()
reloadData()
}
func configure(_ cellType: T.Type, with app: App, for indexPath: IndexPath) -> T {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellType.reuseIdentifier, for: indexPath) as? T else {
fatalError("Unable to dequeue \(cellType)")
}
cell.configure(with: app)
return cell
}
func createDataSource() {
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, app in
switch self.sections[indexPath.section].type {
case "mediumTable":
return self.configure(MediumTableCell.self, with: app, for: indexPath)
case "smallTable":
return self.configure(SmallTableCell.self, with: app, for: indexPath)
default:
return self.configure(FeaturedCell.self, with: app, for: indexPath)
}
}
dataSource?.supplementaryViewProvider = { [weak self] collectionView, kind, indexPath in
guard let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: SectionHeader.reuseIdentifier, for: indexPath) as? SectionHeader else {
return nil
}
guard let firstApp = self?.dataSource?.itemIdentifier(for: indexPath) else { return nil }
guard let section = self?.dataSource?.snapshot().sectionIdentifier(containingItem: firstApp) else { return nil }
if section.title.isEmpty { return nil }
sectionHeader.title.text = section.title
sectionHeader.subtitle.text = section.subtitle
return sectionHeader
}
}
func reloadData() {
var snapshot = NSDiffableDataSourceSnapshot()
snapshot.appendSections(sections)
for section in sections {
snapshot.appendItems(section.items, toSection: section)
}
dataSource?.apply(snapshot)
}
func createCompositionalLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in
let section = self.sections[sectionIndex]
switch section.type {
case "mediumTable":
return self.createMediumTableSection(using: section)
case "smallTable":
return self.createSmallTableSection(using: section)
default:
return self.createFeaturedSection(using: section)
}
}
let config = UICollectionViewCompositionalLayoutConfiguration()
config.interSectionSpacing = 20
layout.configuration = config
return layout
}
func createFeaturedSection(using section: Section) -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
layoutItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 5)
let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .estimated(350))
let layoutGroup = NSCollectionLayoutGroup.horizontal(layoutSize: layoutGroupSize, subitems: [layoutItem])
let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
layoutSection.orthogonalScrollingBehavior = .groupPagingCentered
return layoutSection
}
func createMediumTableSection(using section: Section) -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.33))
let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
layoutItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 5)
let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .fractionalWidth(0.55))
let layoutGroup = NSCollectionLayoutGroup.vertical(layoutSize: layoutGroupSize, subitems: [layoutItem])
let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
layoutSection.orthogonalScrollingBehavior = .groupPagingCentered
let layoutSectionHeader = createSectionHeader()
layoutSection.boundarySupplementaryItems = [layoutSectionHeader]
return layoutSection
}
func createSmallTableSection(using section: Section) -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.2))
let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
layoutItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 0)
let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .estimated(200))
let layoutGroup = NSCollectionLayoutGroup.vertical(layoutSize: layoutGroupSize, subitems: [layoutItem])
let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
let layoutSectionHeader = createSectionHeader()
layoutSection.boundarySupplementaryItems = [layoutSectionHeader]
return layoutSection
}
func createSectionHeader() -> NSCollectionLayoutBoundarySupplementaryItem {
let layoutSectionHeaderSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .estimated(80))
let layoutSectionHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: layoutSectionHeaderSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
return layoutSectionHeader
}
}
Обновление:
Я добавляю кнопку в ячейку CollevtionView, чтобы отображать анимацию, когда пользователь нажимает на нее. Но никто не нашел способа решить мою проблему, описанную выше. Я нашел 2 способа решения проблемы. Первый:
Я удаляю кнопку и добавляю этот код для отображения анимации. . Этот код устраняет описанную выше проблему прокрутки и отображает анимацию при касании ячейки.
Код ячейки:
Но в этом случае иногда я вижу спонтанную анимацию ячейки, когда прокручиваю CollectionView и не нажимаю на ячейку. Как это исправить? Второе:
Код контроллера:
У меня есть UICollectionViewCompositionalLayout. Мое приложение похоже на App Store. В реальном App Store, когда я хочу прокрутить «UICollectionViewCell» с помощью каталога приложений и мой палец случайно нажимает на значок приложения (кнопку действия), я могу без проблем прокручивать дальше. Но в моем приложении, если я сделаю то же самое, я не смогу продолжить прокрутку, потому что срабатывает действие кнопки. Как это исправить? Видео, демонстрирующее проблему: Реальное поведение App Store Мое приложение поведение [b]Код ячейки:[/b] [code]import UIKit
class MediumTableCell: UICollectionViewCell, SelfConfiguringCell { static let reuseIdentifier: String = "MediumTableCell"
let name = UILabel() let subtitle = UILabel() let imageView = UIImageView() let button = UIButton(type: .custom) let buyButton = UIButton(type: .custom)
func configure(_ cellType: T.Type, with app: App, for indexPath: IndexPath) -> T { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellType.reuseIdentifier, for: indexPath) as? T else { fatalError("Unable to dequeue \(cellType)") }
let layoutGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .estimated(200)) let layoutGroup = NSCollectionLayoutGroup.vertical(layoutSize: layoutGroupSize, subitems: [layoutItem])
let layoutSection = NSCollectionLayoutSection(group: layoutGroup) let layoutSectionHeader = createSectionHeader() layoutSection.boundarySupplementaryItems = [layoutSectionHeader]
return layoutSection }
func createSectionHeader() -> NSCollectionLayoutBoundarySupplementaryItem { let layoutSectionHeaderSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.93), heightDimension: .estimated(80)) let layoutSectionHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: layoutSectionHeaderSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top) return layoutSectionHeader } } [/code] [b]Обновление:[/b] Я добавляю кнопку в ячейку CollevtionView, чтобы отображать анимацию, когда пользователь нажимает на нее. Но никто не нашел способа решить мою проблему, описанную выше. Я нашел 2 способа решения проблемы. [b]Первый:[/b] Я удаляю кнопку и добавляю этот код для отображения анимации. . Этот код устраняет описанную выше проблему прокрутки и отображает анимацию при касании ячейки. Код ячейки: [code]import UIKit
class MediumTableCell: UICollectionViewCell, SelfConfiguringCell {
static let reuseIdentifier: String = "MediumTableCell"
var highlightedScale: CGFloat = 0.9
var scaleDownDuration: TimeInterval = 0.4 var scaleUpDuration: TimeInterval = 0.38
override var isHighlighted: Bool { didSet { if oldValue == false && isHighlighted { highlight() } else if oldValue == true && !isHighlighted { unHighlight() } } }
} [/code] Но в этом случае иногда я вижу спонтанную анимацию ячейки, когда прокручиваю CollectionView и не нажимаю на ячейку. Как это исправить? [b]Второе:[/b] Код контроллера: [code]class AppsViewController: UIViewController, UICollectionViewDelegate {
let index = indexPath.item print("\(index)") } [/code] В этом случае я вижу правый indexPath.item, когда нажимаю на ячейку, но анимация не работает. Эта строка не вызывает ячейка [code]let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MediumTableCell.reuseIdentifier, for: indexPath) as! MediumTableCell [/code] Почему?
У меня есть UICollectionViewCompositionalLayout. Мое приложение похоже на App Store. В реальном App Store, когда я хочу прокрутить «UICollectionViewCell» с помощью каталога приложений и мой палец случайно нажимает на значок приложения (кнопку...
У меня есть UICollectionViewCompositionalLayout. Мое приложение похоже на App Store. В реальном App Store, когда я хочу прокрутить «UICollectionViewCell» с помощью каталога приложений и мой палец случайно нажимает на значок приложения (кнопку...
У меня есть UICollectionViewCompositionalLayout. Мое приложение похоже на App Store. В реальном App Store, когда я хочу прокрутить «UICollectionViewCell» с помощью каталога приложений и мой палец случайно нажимает на значок приложения (кнопку...
Здравствуйте, обращаясь к сообщению «Кнопка в PropertyGrid», в котором предлагается решение по добавлению кнопки в wxPropertyGrid. Я реализовал приведенный выше код (как под Linux, так и под Windows), и «графические» элементы работают правильно....
Я хочу изменить высоту элемента раздела и отцентрировать его. Но когда я пытаюсь изменить высоту, я не могу изменить положение Y в своем разделе. Я хочу сделать это: