UicollectionView замерзает после двойного наражения на вращанной/масштабированной ячейке во время горизонтальной прокрутIOS

Программируем под IOS
Ответить
Anonymous
 UicollectionView замерзает после двойного наражения на вращанной/масштабированной ячейке во время горизонтальной прокрут

Сообщение Anonymous »

У меня есть горизонтально прокручивать uicollectionView < /code> in swift.
Inside ScrollViewDidsCroll < /code>, я применяю вращение и масштаб преобразования в видимые ячейки для создания эффекта наклона карты. < /p>
Проблема: < /strong>

Если я дважды используется в коллекции. «Замороженный»-он перестает реагировать на жесты смахивания, и центрированная ячейка остается застрявшей на месте, пока я не перезагружаю данные. Эффект преобразования и предотвращает замораживание сбора после мультитахового или двойного табара?

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

func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard let collectionView = scrollView as? UICollectionView else { return }

for cell in collectionView.visibleCells {
// 1. Calculate the cell's horizontal distance from the center of the screen
let centerX = view.bounds.width / 2
let cellCenter = collectionView.convert(cell.center, to: view)
let distance = centerX - cellCenter.x

// 2. Calculate rotation and scale based on this distance
// The further from the center, the more it rotates and shrinks.
let maxDistance = collectionView.bounds.width / 2
let normalizedDistance = distance / maxDistance // Value from -1 to 1

let maxAngle = CGFloat.pi / 30 // A subtle angle (e.g., 6 degrees)
let angle = maxAngle * normalizedDistance

let minScale: CGFloat = 0.9
let scale = 1.0 - (abs(normalizedDistance) * (1.0 - minScale))

// 3.  Apply the transform
UIView.animate(withDuration: 0.3, delay: 0, options: [.beginFromCurrentState, .allowUserInteraction], animations: {
cell.transform = CGAffineTransform(rotationAngle: angle).scaledBy(x: scale, y: scale)
}, completion: nil)

}
// ✅ Set initial centered index once after layout pass
if !hasSetInitialCenteredIndex {
hasSetInitialCenteredIndex = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.snapToNearestCell()
self.applyTransformToVisibleCells()
}
}
}

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

self.cardsCollectionView.isUserInteractionEnabled = false

isScrolling = true

let velocity = scrollView.panGestureRecognizer.velocity(in: scrollView)
currentScrollDirection = velocity.x == 0 ? 0 : (velocity.x >  0 ? 1 : -1)

}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

self.cardsCollectionView.isUserInteractionEnabled = true

isScrolling = false

let pageWidth = scrollView.frame.size.width
let currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth)

if currentPage == 0 {
let indexPath = IndexPath(item: infinitePlaceholderArray.count - 2, section: 0)
cardsCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)

// Delay snapping until layout is corrected
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.snapToNearestCell()
UIView.animate(withDuration: 0.3) {
self.applyTransformToVisibleCells()
}
}
return

} else if currentPage == infinitePlaceholderArray.count - 1 {
let indexPath = IndexPath(item: 1, section: 0)
cardsCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)

// Delay snapping
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.snapToNearestCell()
UIView.animate(withDuration: 0.3) {
self.applyTransformToVisibleCells()
}
}
return
}

// No wrapping, snap normally
snapToNearestCell()
UIView.animate(withDuration: 0.3) {
self.applyTransformToVisibleCells()
}
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {

self.cardsCollectionView.isUserInteractionEnabled = true

isScrolling = false

snapToNearestCell()
UIView.animate(withDuration: 0.3) {
self.applyTransformToVisibleCells()
}
}
}

func setupInfiniteDataSource() {
// Make sure you have data to work with
guard !placeholderArray.isEmpty else { return }

// [Last Item] + [All Original Items] + [First Item]
infinitePlaceholderArray.append(placeholderArray.last!)
infinitePlaceholderArray.append(contentsOf: placeholderArray)
infinitePlaceholderArray.append(placeholderArray.first!)
}

func applyTransformToVisibleCells() {
guard let collectionView = cardsCollectionView else { return }

for cell in collectionView.visibleCells {
let centerX = view.bounds.width / 2
let cellCenter = collectionView.convert(cell.center, to: view)
let distance = centerX - cellCenter.x

let maxDistance = collectionView.bounds.width / 2
let normalizedDistance = distance / maxDistance

let maxAngle = CGFloat.pi / 30
let angle = maxAngle * normalizedDistance

let minScale: CGFloat = 0.9
let scale = 1.0 - (abs(normalizedDistance) * (1.0 - minScale))

cell.transform = CGAffineTransform(rotationAngle: angle).scaledBy(x: scale, y: scale)
}
}

private func snapToNearestCell() {
guard let collectionView = cardsCollectionView else { return }

let centerX = collectionView.bounds.size.width / 2 + collectionView.contentOffset.x

var closestIndexPath: IndexPath?
var closestDistance: CGFloat = .greatestFiniteMagnitude

for cell in collectionView.visibleCells {
let cellCenterX = cell.center.x
let distance = abs(cellCenterX - centerX)
if distance <  closestDistance {
closestDistance = distance
closestIndexPath = collectionView.indexPath(for: cell)
}
}

if let indexPath = closestIndexPath {
currentlyCenteredIndexPath = indexPath  // Track centered cell
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}

}

private func handleInfiniteScrollWrapping(for scrollView: UIScrollView) {
let pageWidth = scrollView.frame.size.width
let currentPage = Int(floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)

if currentPage == 0 {
let targetIndexPath = IndexPath(item: infinitePlaceholderArray.count - 2, section: 0)
cardsCollectionView.scrollToItem(at: targetIndexPath, at: .centeredHorizontally, animated: false)
} else if currentPage == infinitePlaceholderArray.count - 1 {
let targetIndexPath = IndexPath(item: 1, section: 0)
cardsCollectionView.scrollToItem(at: targetIndexPath, at: .centeredHorizontally, animated: false)
}
}
}
я попробовал: [/b]

[*] Обнаружение нескольких прикосновений в Touchesbegan и вызов my snaptonearestcell () для принудительного снимка. Просмотреть во время анимации SNAP.

ScrollviewWillendDragging и ScrollViewDidEdDecelerating для запуска вручную после мульти-Touch. Вид сбора должен прийти к ближайшей ячейке после мульти-навязчивого события и оставаться прокручиваемым как обычно. Прокрутка прекращает работу полностью, и мне нужно перезагрузить представление сбора, чтобы восстановить взаимодействие.

Подробнее здесь: https://stackoverflow.com/questions/797 ... ing-horizo
Ответить

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

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

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

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

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