2016-12-21 17 views
0

私は(も各項目のインデックスを示す)写真で描かれているモックアップのようなUICollectionViewをレイアウトしようとしています:スウィフト:UICollectionビューのレイアウトの問題

enter image description here

コードI現在、試してみて、これを達成するために持っていることである:のviewDidLoadで

:ファイルの後に続いて

collectionView.dataSource = self 
    collectionView.delegate = self 

    flowLayout.scrollDirection = .horizontal 
    flowLayout.minimumLineSpacing = 5 
    flowLayout.minimumInteritemSpacing = 5 
    flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 5) 

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
    let totalWidth = collectionView.bounds.size.width 
    let totalHeight = collectionView.bounds.size.height 
    let heightOfView = totalHeight/3 
    let numberOfCellsPerRow = 1 
    let dimensions = CGFloat(Int(totalWidth)/numberOfCellsPerRow) 
    if (indexPath.item == 4) { 
     return CGSize(width: collectionView.bounds.size.width, height: heightOfView) 
    } else { 
     return CGSize(width: dimensions/2, height: heightOfView) 
    } 
} 

このコードは、所望の効果を持っていない、とこのようになりますUICollectionViewを生産している:

enter image description here

あなたが見ることができるように、細胞がさえUICollectionViewではない、と右側のセルはスクロールスペースにオーバーフローします。項目間のセクションギャップが間違っていて、5番目にスクロールしない限り、画面の右側に大きなセルが表示されます。

+0

はあなたが、これは横スクロールであることを確認しているflowLayout.scrollDirection = .horizo​​ntal使用? – Mohammadalijf

+0

垂直スクロールでは、すべて垂直に順番に並んでいきます。 –

+0

サイズの計算に 'minimumLineSpacing'と' minimumInteritemSpacing'を追加してみてください。 – Larme

答えて

1

標準のUICollectionViewFlowLayoutクラスでは、そのようなレイアウトを作成することはできません。まず、UICollectionViewに関連するWWDCビデオを見てください。そのレイアウトはhttps://developer.apple.com/videos/play/wwdc2012/219/です。その後、サンプルコードでSwiftチュートリアルをチェックして開始することができます。http://swiftiostutorials.com/tutorial-creating-custom-layouts-uicollectionview/

最も簡単な作業は、カスタムUICollectionViewLayoutのようなコードになります。出発点としてこれを使用します。

@interface UICollectionViewCustomLayout() 

@property (nonatomic) NSArray<UICollectionViewLayoutAttributes *> *attributes; 
@property (nonatomic) CGSize size; 

@end 

@implementation UICollectionViewCustomLayout 

- (void)prepareLayout 
{ 
    [super prepareLayout]; 

    NSMutableArray<UICollectionViewLayoutAttributes *> *attributes = [NSMutableArray new]; 

    id<UICollectionViewDelegate> delegate = (id<UICollectionViewDelegate>)self.collectionView.delegate; 
    id<UICollectionViewDataSource> dataSource = (id<UICollectionViewDataSource>)self.collectionView.dataSource; 

    NSInteger count = [dataSource collectionView:self.collectionView numberOfItemsInSection:0]; 
    CGFloat collectionViewWidth = CGRectGetWidth(self.collectionView.frame); 
    CGFloat collectionViewHeight = CGRectGetHeight(self.collectionView.frame); 
    CGFloat rowHeight = floor(collectionViewHeight/3); 
    NSUInteger numberOfPages = count/5; 
    if (count % 5) { 
     numberOfPages++; 
    } 

    for (NSInteger item = 0; item < count; item++) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:0]; 
     UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 

     NSInteger index = item % 5; 
     NSInteger page = item/5; 
     CGFloat width = index == 4 ? collectionViewWidth : collectionViewWidth/2; 
     CGSize size = CGSizeMake(width, rowHeight); 
     CGFloat x = page * collectionViewWidth + (index % 2 == 0 ? 0 : collectionViewWidth/2); 
     CGFloat y = (index/2) * rowHeight; 
     CGPoint origin = CGPointMake(x, y); 
     CGRect frame = CGRectZero; 
     frame.size = size; 
     frame.origin = origin; 
     attribute.frame = frame; 
     [attributes addObject:attribute]; 
    } 
    self.attributes = attributes; 

    self.size = CGSizeMake(numberOfPages * collectionViewWidth, collectionViewHeight); 
} 

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 
{ 
    NSMutableArray<UICollectionViewLayoutAttributes *> *result = [NSMutableArray new]; 
    for (UICollectionViewLayoutAttributes *attribute in self.attributes) { 
     if (CGRectIntersectsRect(attribute.frame, rect)) { 
      [result addObject:attribute]; 
     } 
    } 
    return result; 
} 

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"indexPath.section == %@ AND indexPath.item == %@", @(indexPath.section), @(indexPath.item)]; 
    UICollectionViewLayoutAttributes *attributes = [self.attributes filteredArrayUsingPredicate:predicate].firstObject; 
    return attributes; 
} 

- (CGSize)collectionViewContentSize 
{ 
    return self.size; 
} 

@end 

とコントローラを:

// Views 
#import "UICollectionViewCustomLayout.h" 

@interface ViewController() <UICollectionViewDataSource, UICollectionViewDelegate> 

@property (nonatomic) UICollectionView *collectionView; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[UICollectionViewCustomLayout new]]; 
    self.collectionView.backgroundColor = [UIColor whiteColor]; 
    self.collectionView.frame = self.view.bounds; 
    self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    self.collectionView.delegate = self; 
    self.collectionView.dataSource = self; 
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class])]; 
    [self.view addSubview:self.collectionView]; 
} 

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
{ 
    return 10; 
} 

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath 
{ 
    NSArray *colors = @[[UIColor redColor], [UIColor blueColor], [UIColor grayColor], [UIColor greenColor], [UIColor purpleColor], [UIColor cyanColor]]; 

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class]) forIndexPath:indexPath]; 
    cell.contentView.backgroundColor = colors[arc4random() % colors.count]; 
    cell.contentView.alpha = (arc4random() % 500 + 500)/1000.0; 
    return cell; 
} 

@end 

enter image description here

+0

返事をありがとう。 FlowLayoutが機能しない場合、このスタイルのレイアウトを実現する別の方法はありますか? –

+0

@RyanHamptonすぐに私の答えを更新します。 –

+0

私はコードを見てきましたが、複雑なように6項目のグリッドに変更するだけです。私は行間の大きな間隔をどのように解決できるのか分かりますか?コレクションビューは3つ下のアイテムと2つのアイテムに分かれていますか? –