OK, Antwort ist nein, es gibt keine Möglichkeit, dies zu tun, ohne UICollectionViewFlowLayout zu unterklassifizieren.
Das Unterklassen ist jedoch für jeden, der dies in Zukunft liest, unglaublich einfach.
Zuerst habe ich den Unterklassenaufruf eingerichtet MyCollectionViewFlowLayout
und dann im Interface Builder das Layout der Sammlungsansicht in Benutzerdefiniert geändert und meine Unterklasse für das Flusslayout ausgewählt.
Da Sie dies auf diese Weise tun, können Sie in IB keine Artikelgrößen usw. angeben. In MyCollectionViewFlowLayout.m habe ich diese ...
- (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);
}
Dadurch werden alle Größen für mich und die Bildlaufrichtung festgelegt.
Dann ...
- (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);
}
Dies stellt sicher, dass das Scrollen mit einem Rand von 5,0 am linken Rand endet.
Das war alles was ich tun musste. Ich musste das Ablauflayout überhaupt nicht im Code festlegen.
targetContentOffsetForProposedContentOffset:withVelocity
wird nicht für mich gerufen, wenn ich scrolle. Was ist los?Dans Lösung ist fehlerhaft. Der Benutzer kann nicht gut mit dem Schnippen umgehen. Die Fälle, in denen der Benutzer schnell schnippt und der Bildlauf sich nicht so stark bewegt, weisen Animationsfehler auf.
Meine vorgeschlagene alternative Implementierung hat dieselbe Paginierung wie zuvor vorgeschlagen, behandelt jedoch das Wechseln zwischen Seiten.
quelle
Schnelle Version der akzeptierten Antwort.
Gültig für Swift 5 .
quelle
Hier ist meine Implementierung in Swift 5 für vertikales zellbasiertes Paging:
Einige Notizen:
itemSize
Größe tatsächlich mit der Größe des Elements übereinstimmt, da dies häufig ein Problem darstellt, insbesondere bei VerwendungcollectionView(_:layout:sizeForItemAt:)
. Verwenden Sie stattdessen eine benutzerdefinierte Variable mit itemSize.self.collectionView.decelerationRate = UIScrollView.DecelerationRate.fast
.Hier ist eine horizontale Version (habe sie nicht gründlich getestet, bitte verzeihen Sie Fehler):
Dieser Code basiert auf dem Code, den ich in meinem persönlichen Projekt verwende. Sie können ihn hier überprüfen, indem Sie ihn herunterladen und das Beispielziel ausführen .
quelle
Während diese Antwort mir sehr geholfen hat, gibt es ein merkliches Flackern, wenn Sie auf einer kleinen Strecke schnell wischen. Es ist viel einfacher, es auf dem Gerät zu reproduzieren.
Ich fand, dass dies immer passiert, wenn
collectionView.contentOffset.x - proposedContentOffset.x
undvelocity.x
verschiedene Singen haben.Meine Lösung bestand darin, sicherzustellen, dass dies
proposedContentOffset
mehr ist alscontentOffset.x
wenn die Geschwindigkeit positiv ist, und weniger, wenn sie negativ ist. Es ist in C #, sollte aber ziemlich einfach in Ziel C zu übersetzen sein:Dieser Code wird verwendet
MinContentOffset
,MaxContentOffset
undSnapStep
die trivial sein sollte für Sie zu definieren. In meinem Fall stellte sich heraus, dass sie es warenquelle
Nach langen Tests fand ich eine Lösung zum Einrasten in die Mitte mit einer benutzerdefinierten Zellenbreite (jede Zelle hat eine unterschiedliche Breite), die das Flackern behebt. Fühlen Sie sich frei, das Skript zu verbessern.
quelle
Beziehen Sie sich auf diese Antwort von Dan Abramov in der Swift-Version
oder hier https://gist.github.com/katopz/8b04c783387f0c345cd9
quelle
Für alle, die nach einer Lösung suchen, die ...
collectionView.contentInset
(und safeArea auf dem iPhone X)dann siehe unten ...
quelle
Hier ist meine Swift-Lösung für eine horizontal scrollende Sammlungsansicht. Es ist einfach, süß und vermeidet jegliches Flackern.
quelle
itemSize
??pageWidth()
sollte verwendet werden,minimumLineSpacing
da es horizontal scrollt. In meinem Fall habe ich einecontentInset
Ansicht für die Sammlung, damit die erste und die letzte Zelle zentriert werden könnenlet xOffset = pageWidth() * index - collectionView.contentInset.left
.Ein kleines Problem, das bei der Verwendung von targetContentOffsetForProposedContentOffset aufgetreten ist, ist ein Problem, bei dem die letzte Zelle nicht an den neuen Punkt angepasst wurde, den ich zurückgegeben habe.
Ich fand heraus, dass der von mir zurückgegebene CGPoint einen Y-Wert hatte, der größer als zulässig war, und verwendete daher am Ende meiner Implementierung von targetContentOffsetForProposedContentOffset den folgenden Code:
Nur um es klarer zu machen, ist dies meine vollständige Layout-Implementierung, die nur das vertikale Paging-Verhalten imitiert:
hoffentlich spart dies jemandem etwas Zeit und Kopfschmerzen
quelle
Ich ziehe es vor, dem Benutzer das Durchblättern mehrerer Seiten zu erlauben. Hier ist meine Version von
targetContentOffsetForProposedContentOffset
(basierend auf der DarthMike-Antwort) für das vertikale Layout.quelle
Die Antwort von Fogmeisters hat bei mir funktioniert, es sei denn, ich habe bis zum Ende der Zeile gescrollt. Meine Zellen passen nicht gut auf den Bildschirm, sodass sie bis zum Ende scrollen und mit einem Ruck zurückspringen, sodass die letzte Zelle immer den rechten Bildschirmrand überlappt.
Um dies zu verhindern, fügen Sie am Anfang der Methode targetcontentoffset die folgende Codezeile hinzu
quelle
@ André Abreu Code
Swift3-Version
quelle
Swift 4
Die einfachste Lösung für die Sammlungsansicht mit Zellen einer Größe (horizontaler Bildlauf):
quelle
Eine kürzere Lösung (vorausgesetzt, Sie speichern Ihre Layoutattribute zwischen):
Um dies in einen Zusammenhang zu bringen:
quelle
Um sicherzustellen, dass es in der Swift-Version funktioniert (jetzt Swift 5), habe ich die Antwort verwendet von @ André Abreu verwendet und einige weitere Informationen hinzugefügt:
Wenn Sie UICollectionViewFlowLayout unterklassifizieren, funktioniert die Funktion "override func awakeFromNib () {}" nicht (ich weiß nicht warum). Stattdessen habe ich "override init () {super.init ()}" verwendet.
Dies ist mein Code in der Klasse SubclassFlowLayout: UICollectionViewFlowLayout {}:
Stellen Sie nach dem Unterklassen sicher, dass Sie dies in ViewDidLoad () einfügen:
quelle
Für diejenigen, die nach einer Lösung in Swift suchen:
quelle
Hier ist eine Demo für das Blättern nach Zellen (wenn Sie schnell scrollen und nicht eine oder mehrere Zellen überspringen): https://github.com/ApesTalk/ATPagingByCell
quelle