Ограничение вертикального перемещения UIAttachmentBehavior внутри UICollectionView
У меня есть горизонтальный UICollectionView
с пользовательским UICollectionViewFlowLayout
, который имеет UIAttachmentBehavior
, установленный в каждой ячейке, чтобы придавать ему упругость при прокрутке влево и вправо. Поведение имеет следующие свойства:
attachmentBehavior.length = 1.0f;
attachmentBehavior.damping = 0.5f;
attachmentBehavior.frequency = 1.9f;
Когда новая ячейка добавляется в представление коллекции, она добавляется снизу, а затем анимируется в ее положение, также используя UIAttachmentBehavior
. Естественно, он подпрыгивает вверх и вниз, пока он не встанет на свое место. До сих пор все работает так, как ожидалось.
![enter image description here]()
Проблема, с которой я начинаю появляться, когда просмотр коллекции прокручивается влево или вправо до того, как вновь добавленная ячейка остановилась. Добавляет левый и правый bounciness к вверх и вниз, к которому уже добавлена ячейка. Это приводит к очень странному круговому движению в ячейке.
![enter image description here]()
Мой вопрос: возможно ли остановить вертикальное движение UIAttachmentBehavior во время прокрутки просмотра коллекции? Я пробовал разные подходы, такие как использование нескольких типов вложений и отключение прокрутки в представлении коллекции до тех пор, пока вновь добавленная ячейка не успокоится, но не похоже, что они перестали это делать.
Ответы
Ответ 1
Я прибегал к отключению прокрутки в представлении коллекции за определенное количество времени после добавления новой ячейки, а затем удаление поведения вложения после того, как прошло это время, с использованием свойства action
, а затем добавление нового поведения вложения снова немедленно.
Таким образом, я уверен, что восходящая анимация останавливается до того, как просмотр коллекции будет прокручиваться влево или вправо, но при прокрутке все еще остается левое/правое оживление.
Конечно, это не самое элегантное решение, но оно работает.
Ответ 2
Один из способов решения этой проблемы - использовать унаследованное свойство .action поведения приложения.
Сначала вам нужно настроить пару переменных, что-то вроде (происходит из памяти, непроверенный код):
BOOL limitVerticalMovement = TRUE;
CGFloat staticCenterY = CGRectGetHeight(self.collectionView.frame) / 2;
Задайте их как свойства вашего пользовательского UICollectionViewFlowLayout
Когда вы создаете поведение вложения:
UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:center];
attachment.damping = 1.0f;
attachment.frequency = 1.5f;
attachment.action = ^{
if (!limitVerticalMovement) return;
CGPoint center = item.center;
center.y = staticCenterY;
item.center = center;
};
Затем вы можете включать и выключать предельную функцию, устанавливая, по мере необходимости, limitVerticalMovement.
Ответ 3
Вы пытались вручную удалить анимации из ячеек с помощью CALayer
removeAllAnimations
?
Ответ 4
Вы хотите удалить поведение, когда просмотр коллекции начнет прокручиваться, или, возможно, значительно уменьшить упругость, чтобы он оставался плавно, но быстро. Если вы думаете об этом, то, что вы видите, является реалистичным движением для описанного вами поведения привязанности.
Чтобы поддерживать вертикальное подпрыгивание с той же скоростью, но не допускать горизонтального подпрыгивания, вам нужно добавить другое поведение - как поведение столкновения с границами слева и справа от каждой добавленной ячейки. Это немного увеличит сложность физики и может повлиять на производительность прокрутки, но стоит попробовать.
Ответ 5
Если вы используете iOS 9 и выше, то скользящая функция в классе вложения будет отлично работать для этого задания:
class func slidingAttachmentWithItem(_ item: UIDynamicItem,
attachmentAnchor point: CGPoint,
axisOfTranslation axis: CGVector) -> Self
его можно легко использовать, и он очень эффективен для скользящих [документации Apple] 1
Ответ 6
Вот как мне это удалось.
FloatRange ограничивает диапазон вложения, поэтому, если вы хотите, чтобы он прошел весь путь вверх и вниз по экрану, вы просто установили действительно большие числа.
Это происходит внутри func узнаетPanGesture (отправитель: UIPanGestureRecognizer) {}
let location = sender.location(in: yourView.superview)
var direction = "Y"
var center = CGPoint(x: 0, y: 0)
if self.direction == "Y" {center.y = 1}
if self.direction == "X" {center.x = 1}
let sliding = UIAttachmentBehavior.slidingAttachment(with: youView, attachmentAnchor: location, axisOfTranslation: CGVector(dx: center.x, dy: center.y))
sliding.attachmentRange = UIFloatRange(minimum: -2000, maximum: 2000)
animator = UIDynamicAnimator(referenceView: self.superview!)
animator.addBehavior(sliding)