Ich habe Zellen unterschiedlicher Höhe auf einem horizontal scrollenden , die die Zellen gleichmäßig zu verteilen scheint vertikal leeren Bereich zwischen den Zellen und ich möchte sie nach oben ausrichten und haben die Variable leeren Raum am unteren Rand jeder Spalte.Wie richten Sie die UICollectionViewCells in einer UICollectionView vertikal aus?
Antwort
Ich kann mir vorstellen, dass Sie ein UICollectionViewFlowLayout zum Layout Ihrer Zellen verwenden. Ich denke nicht, dass Sie dies mit einem Fließschema tun können. Sie müssen wahrscheinlich eine benutzerdefinierte Unterklasse von UICollectionViewLayout schreiben, um die oberen Kanten jeder Zelle auszurichten.
Dies ist keine sehr schöne Lösung, aber wie wäre es, wenn Sie alle Ihre Zellen auf die gleiche Größe zwingen und die Beschränkungen in Ihrer Zelle einrichten, um den Inhalt an der Spitze auszurichten? Dies könnte das Aussehen simulieren, ohne dass Sie UICollectionViewLayout ableiten müssen.
Ich erweiterte meine UICollectionViewFlowLayout für meine UICollectionView bereitgestellt. Das folgende Überschreiben hat für mich funktioniert.
#import "TopAlignedCollectionViewFlowLayout.h"
const NSInteger kVerticalSpacing = 10;
@implementation TopAlignedCollectionViewFlowLayout
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray* attributesToReturn = [super layoutAttributesForElementsInRect:rect];
for (UICollectionViewLayoutAttributes* attributes in attributesToReturn) {
if (nil == attributes.representedElementKind) {
NSIndexPath* indexPath = attributes.indexPath;
attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame;
}
}
return attributesToReturn;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes* currentItemAttributes =
[super layoutAttributesForItemAtIndexPath:indexPath];
UIEdgeInsets sectionInset = [(UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout sectionInset];
if (indexPath.item == 0) {
CGRect frame = currentItemAttributes.frame;
frame.origin.y = sectionInset.top;
currentItemAttributes.frame = frame;
return currentItemAttributes;
}
NSIndexPath* previousIndexPath = [NSIndexPath indexPathForItem:indexPath.item-1 inSection:indexPath.section];
CGRect previousFrame = [self layoutAttributesForItemAtIndexPath:previousIndexPath].frame;
CGFloat previousFrameRightPoint = previousFrame.origin.y + previousFrame.size.height + kVerticalSpacing;
CGRect currentFrame = currentItemAttributes.frame;
CGRect strecthedCurrentFrame = CGRectMake(currentFrame.origin.x,
0,
currentFrame.size.width,
self.collectionView.frame.size.height
);
if (!CGRectIntersectsRect(previousFrame, strecthedCurrentFrame)) {
CGRect frame = currentItemAttributes.frame;
frame.origin.y = frame.origin.y = sectionInset.top;
currentItemAttributes.frame = frame;
return currentItemAttributes;
}
CGRect frame = currentItemAttributes.frame;
frame.origin.y = previousFrameRightPoint;
currentItemAttributes.frame = frame;
return currentItemAttributes;
}
@end
ich portierte dies Xamarin/Monotouch für mein Projekt und dachte, es
public class TopAlignedCollectionViewFlowLayout : UICollectionViewFlowLayout
{
const int VerticalSpacing = 10;
public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(RectangleF rect)
{
var attributesToReturn = base.LayoutAttributesForElementsInRect(rect);
foreach (UICollectionViewLayoutAttributes attributes in attributesToReturn)
{
if (attributes.RepresentedElementKind == null)
{
var indexPath = attributes.IndexPath;
attributes.Frame = this.LayoutAttributesForItem(indexPath).Frame;
}
}
return attributesToReturn;
}
public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath indexPath)
{
var currentItemAttributes = base.LayoutAttributesForItem(indexPath);
UIEdgeInsets sectionInset = ((UICollectionViewFlowLayout) this.CollectionView.CollectionViewLayout).SectionInset;
if (indexPath.Item == 0)
{
var frame1 = currentItemAttributes.Frame;
frame1.Y = sectionInset.Top;
currentItemAttributes.Frame = frame1;
return currentItemAttributes;
}
var previousIndexPath = NSIndexPath.FromItemSection(indexPath.Item - 1, indexPath.Section);
var previousFrame = this.LayoutAttributesForItem(previousIndexPath).Frame;
var previousFrameRightPoint = previousFrame.Y + previousFrame.Size.Height + VerticalSpacing;
var currentFrame = currentItemAttributes.Frame;
var strecthedCurrentFrame = new RectangleF(currentFrame.X, 0, currentFrame.Size.Width, this.CollectionView.Frame.Size.Height);
if (!previousFrame.IntersectsWith(strecthedCurrentFrame))
{
var frame = currentItemAttributes.Frame;
frame.Y = frame.Y = sectionInset.Top;
currentItemAttributes.Frame = frame;
return currentItemAttributes;
}
RectangleF frame2 = currentItemAttributes.Frame;
frame2.Y = previousFrameRightPoint;
currentItemAttributes.Frame = frame2;
return currentItemAttributes;
}
}
Guter Ausgangspunkt für andere Ableitungen aus dem Layout nützlich sein könnte. Lief wie am Schnürchen! –
Ich habe diese Lösung versucht, aber es funktioniert nicht für mich mit statischer Zellenbreite und dynamischer Zellenhöhe. Die Fließrichtung ist horizontal. – shujaat
shujaat, hast du das jemals herausgefunden? – tofutim