2013-06-10 12 views

答えて

0

UICollectionViewFlowLayoutを使用してセルをレイアウトしていると思います。私はあなたがフローレイアウトでこれを行うことができるとは思わない。 UICollectionViewLayoutのカスタムサブクラスを作成して、各セルの上端を揃える必要があります。

これは非常にきれいな解決策ではありませんが、すべてのセルを同じサイズに強制し、セル内の制約を設定してコンテンツを上部に揃えるのはどうでしょうか?これは、UICollectionViewLayoutをサブクラス化することなく、あなたが行っている外観をシミュレートすることができます。

12

UICollectionViewに提供されたUICollectionViewFlowLayoutを拡張しました。次のオーバーライドは私のために働いた。

#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 
+0

グレート出発点となると考えていました。チャームのように働いた! –

+1

私はこのソリューションを試しましたが、静的なセル幅と動的なセルの高さで私のために働いていません。流れ方向は水平である。 – shujaat

+0

shujaat、あなたはこれを理解したことがありますか? – tofutim

3

私は私のプロジェクトのためにXamarin/MonoTouchでこれを移植し、それがレイアウトから他の派生のために有用

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; 
    } 

} 
+0

この種の作品(OSXに移植されました)が、私のアイテムは次の行には行きません – tofutim

+0

このコードには再帰的な悪さがあります... – tofutim

関連する問題