Сбои UICollectionView при удалении разделов с использованием композиционных макетов и различающихся источников данных.IOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Сбои UICollectionView при удалении разделов с использованием композиционных макетов и различающихся источников данных.

Сообщение Anonymous »

У меня возникла проблема при отрисовке съемных разделов в представлениях моей коллекции. Настройка следующая:
Представление коллекции состоит из двух разделов. Первая содержит только одну ячейку, при нажатии на которую активируется обновление снимка, удаляющее разделы из представления коллекции. Второй раздел содержит несколько ячеек, прокручивающихся ортогонально.
Проблема возникает при прокрутке второго раздела и последующем нажатии единственной ячейки в первом.
Я ожидаю поведения: первый раздел будет удален, а затем плавно переместится на первое место.
Что Я вижу, как ортогонально прокручиваемый участок мерцает и прыгает, пока анимация не завершится.
Вот несколько примеров того, чего я ожидаю и что происходит.
Вот несколько примеров того, чего я ожидаю и что происходит.
Вот несколько примеров того, чего я ожидаю и что происходит.
p>



Ожидается (без прокрутки)
Неожиданно (фактический результат)





Изображение


Изображение




Вот фрагмент кода, который можно разместить на игровой площадке для тестирования (Xcode 15.3, iOS 17). Обратите внимание, что это всего лишь пример, который я попытался извлечь из реального кода, который более сложен.

Код: Выделить всё

import UIKit
import PlaygroundSupport

var onTap = {
removeSection()
}

// Rainbow colored cells
final class Cell: UICollectionViewCell {
override func prepareForReuse() {
contentView.backgroundColor = .clear
}

func configure(with color: UIColor) {
contentView.backgroundColor = color
}
}

// The cell that when tapped, triggers the section removal (note that selection isn't being handled through didSelectItem.
final class RemovableCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
contentView.backgroundColor = .systemCyan
contentView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap)))
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

@objc
func tap() {
onTap()
}
}

// Registrations for the cells
let cellRegistration = UICollectionView.CellRegistration { cell, indexPath, _ in
let colors: [UIColor] = [.red, .orange, .yellow, .green, .blue]
cell.configure(with: colors[indexPath.item % colors.count])
}
let removableCellRegistration = UICollectionView.CellRegistration { cell, indexPath, _ in }

let removableSection: NSCollectionLayoutSection = {
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .estimated(120))
let item = NSCollectionLayoutItem(layoutSize: itemSize)

let group = NSCollectionLayoutGroup.horizontal(layoutSize: itemSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)

return section
}()

// Sections definitions
let orthogonallyScrollingSection: NSCollectionLayoutSection = {
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .fractionalHeight(1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)

let groupSize = NSCollectionLayoutSize(
widthDimension: .estimated(100),
heightDimension: .fractionalHeight(0.2))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .continuous

return section
}()

// Collection view construction, please don't mind the mess.
var removeSectionAvailable = true
let layout = UICollectionViewCompositionalLayout { section, _ in
if section == 0, removeSectionAvailable {
removableSection
} else {
orthogonallyScrollingSection
}
}
let frame = CGRect(x: 0, y: 0, width: 300, height: 500)
let view = UICollectionView(frame: frame, collectionViewLayout: layout)
let dataSource = UICollectionViewDiffableDataSource(collectionView: view) { collectionView, indexPath, itemIdentifier in
if indexPath.section == 0, removeSectionAvailable {
return collectionView.dequeueConfiguredReusableCell(
using: removableCellRegistration,
for: indexPath,
item: itemIdentifier)
} else {
return collectionView.dequeueConfiguredReusableCell(
using: cellRegistration,
for: indexPath,
item: itemIdentifier
)
}
}

var snapshot = NSDiffableDataSourceSnapshot()
snapshot.appendSections([0, 1])
snapshot.appendItems([0], toSection: 0)
snapshot.appendItems([1, 2, 3, 4, 5, 6], toSection: 1)
dataSource.apply(snapshot)

func removeSection() {
removeSectionAvailable = false
snapshot.deleteSections([0])
dataSource.apply(snapshot)
}

// Playground setup
PlaygroundPage.current.liveView = view
PlaygroundPage.current.needsIndefiniteExecution = true
Все советы приветствуются!


Подробнее здесь: https://stackoverflow.com/questions/786 ... ayouts-and
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»