Хорошо, ответ - нет, это невозможно сделать без подкласса UICollectionViewFlowLayout.
Однако создать подклассы будет невероятно легко для любого, кто будет читать это в будущем.
Сначала я настроил вызов подкласса, MyCollectionViewFlowLayout
а затем в построителе интерфейса изменил макет представления коллекции на «Пользовательский» и выбрал подкласс макета потока.
Поскольку вы делаете это таким образом, вы не можете указывать размеры элементов и т.д ... в IB, поэтому в MyCollectionViewFlowLayout.m у меня есть это ...
- (void)awakeFromNib
{
self.itemSize = CGSizeMake(75.0, 75.0);
self.minimumInteritemSpacing = 10.0;
self.minimumLineSpacing = 10.0;
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
}
Это устанавливает для меня все размеры и направление прокрутки.
Затем ...
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalOffset = proposedContentOffset.x + 5;
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray *array = [super layoutAttributesForElementsInRect:targetRect];
for (UICollectionViewLayoutAttributes *layoutAttributes in array) {
CGFloat itemOffset = layoutAttributes.frame.origin.x;
if (ABS(itemOffset - horizontalOffset) < ABS(offsetAdjustment)) {
offsetAdjustment = itemOffset - horizontalOffset;
}
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
Это гарантирует, что прокрутка заканчивается с полем 5,0 на левом краю.
Это все, что мне нужно было сделать. Мне вообще не нужно было устанавливать схему потока в коде.
targetContentOffsetForProposedContentOffset:withVelocity
меня не зовут, когда я прокручиваю. В чем дело?Решение Дэна ошибочно. Он плохо справляется с щелчком пользователя. В случаях, когда пользователь быстро щелкает мышью, а прокрутка не так сильно перемещается, возникают сбои анимации.
Предлагаемая мной альтернативная реализация имеет ту же разбивку на страницы, что и ранее, но обрабатывает переключение пользователем между страницами.
источник
Быстрая версия принятого ответа.
Действительно для Swift 5 .
источник
Вот моя реализация в Swift 5 для вертикального разбиения по страницам на основе ячеек:
Некоторые примечания:
itemSize
действительно ли ваш размер соответствует размеру элемента, поскольку это часто проблема, особенно при использованииcollectionView(_:layout:sizeForItemAt:)
, вместо этого используйте пользовательскую переменную с itemSize.self.collectionView.decelerationRate = UIScrollView.DecelerationRate.fast
.Вот горизонтальная версия (тщательно не тестировала, простите, пожалуйста, за ошибки):
Этот код основан на коде, который я использую в своем личном проекте, вы можете проверить его здесь , загрузив его и запустив целевой объект Example.
источник
Хотя этот ответ мне очень помог, при быстром смахивании на небольшом расстоянии появляется заметное мерцание. Воспроизвести его на устройстве намного проще.
Я обнаружил, что это всегда бывает, когда
collectionView.contentOffset.x - proposedContentOffset.x
иvelocity.x
поет разные.Мое решение заключалось в том, чтобы убедиться, что
proposedContentOffset
это больше, чемcontentOffset.x
если скорость положительная, и меньше, если она отрицательная. Это на C #, но должно быть довольно просто перевести на Objective C:Этот код используется
MinContentOffset
,MaxContentOffset
и выSnapStep
должны легко его определить. В моем случае они оказалисьисточник
После долгого тестирования я нашел решение для привязки к центру с настраиваемой шириной ячейки (каждая ячейка имеет разную ширину), которая устраняет мерцание. Не стесняйтесь улучшать сценарий.
источник
обратитесь к этому ответу Дэна Абрамова, вот версия Swift
или суть здесь https://gist.github.com/katopz/8b04c783387f0c345cd9
источник
Для тех, кто ищет решение, которое ...
collectionView.contentInset
(и safeArea на iPhone X)тогда смотрите ниже ...
источник
Вот мое решение Swift для просмотра коллекции с горизонтальной прокруткой. Это просто, мило и без мерцания.
источник
itemSize
??pageWidth()
следует использовать,minimumLineSpacing
поскольку он прокручивается по горизонтали. В моем случае у меня есть представлениеcontentInset
коллекции, чтобы можно было центрировать первую и последнюю ячейку, поэтому я используюlet xOffset = pageWidth() * index - collectionView.contentInset.left
.небольшая проблема, с которой я столкнулся при использовании targetContentOffsetForProposedContentOffset, - это проблема с последней ячейкой, которая не настраивается в соответствии с новой точкой, которую я вернул.
Я обнаружил, что CGPoint, который я вернул, имеет значение Y больше разрешенного, поэтому я использовал следующий код в конце моей реализации targetContentOffsetForProposedContentOffset:
просто для большей ясности это моя полная реализация макета, которая просто имитирует поведение вертикального разбиения на страницы:
надеюсь, это сэкономит кому-то время и избавит от головной боли
источник
Я предпочитаю позволять пользователю пролистывать несколько страниц. Итак, вот моя версия
targetContentOffsetForProposedContentOffset
(основанная на ответе DarthMike) для вертикальной компоновки.источник
Ответ Фогмейстера сработал для меня, если я не прокрутил до конца строки. Мои ячейки не помещаются аккуратно на экране, поэтому он прокручивается до конца и рывком отскакивает назад, так что последняя ячейка всегда перекрывает правый край экрана.
Чтобы предотвратить это, добавьте следующую строку кода в начало метода targetcontentoffset
источник
Кодекс @ André Abreu
Версия Swift3
источник
Swift 4
Самое простое решение для просмотра коллекции с ячейками одного размера (горизонтальная прокрутка):
источник
Более короткое решение (при условии, что вы кешируете свои атрибуты макета):
Чтобы поместить это в контекст:
источник
Чтобы убедиться, что он работает в версии Swift (сейчас swift 5), я использовал ответ от @ André Abreu, я добавляю дополнительную информацию:
При создании подкласса UICollectionViewFlowLayout «функция переопределения awakeFromNib () {}» не работает (не знаю почему). Вместо этого я использовал "override init () {super.init ()}"
Это мой код, помещенный в класс SubclassFlowLayout: UICollectionViewFlowLayout {}:
После создания подкласса обязательно поместите это в ViewDidLoad ():
источник
Для тех, кто ищет решение на Swift:
источник
Вот демонстрация разбиения на страницы по ячейкам (при быстрой прокрутке, без пропуска одной или нескольких ячеек): https://github.com/ApesTalk/ATPagingByCell
источник