0

カスタム レイアウト オブジェクトを使用せずに UICollectionView を実装すると、再利用可能なセルが 16 個すべて表示されます。つまり、セクションに 16 個の項目がある 1 つのセクションがあります。カスタム レイアウト オブジェクトを作成すると、1 つのセルしか表示されません。セクション数を 5 に変更すると、5 つのセルが表示されます。レイアウト オブジェクトを使用すると collectionView がセクションを描画し、デフォルト グリッドを使用すると項目を描画するのはなぜですか???? 何か不足していますか?

ここで UICollectionViewLayout をサブクラス化します。

 static NSString * const kPadLayoutType = @"gridPads";

 - (id)initWithCoder:(NSCoder *)aDecoder
 {
     self = [super initWithCoder:aDecoder];
     if(self) {
         [self setup];
     }
     return self;
 }

 - (void)setup
 {
     self.itemInsets = UIEdgeInsetsMake(22.0f, 22.0f, 13.0f, 22.0f);
     self.itemSize = CGSizeMake(125.0f, 125.0f);
     self.interItemSpacingY = 12.0f;
     self.numberOfColumns = 4;
 }

 # pragma mark _____Layout

 - (void)prepareLayout
 {
     NSMutableDictionary *newLayoutInfo = [NSMutableDictionary dictionary];
     NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];

     NSInteger sectionCount = [self.collectionView numberOfSections];
     NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];

     for(NSInteger section = 0; section < sectionCount; section++) {
         NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];

         for(NSInteger item = 0; item < itemCount; item++) {
             indexPath = [NSIndexPath indexPathForItem:item inSection:section];

             UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
             itemAttributes.frame = [self frameForPadAtIndexPath:indexPath];

             cellLayoutInfo[indexPath] = itemAttributes;
         }
     }
     newLayoutInfo[kPadLayoutType] = cellLayoutInfo;
     self.layoutInfo = newLayoutInfo;
 }

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

 - (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect
 {
     NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];

     [self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSString *elementIdentifier,
                                                     NSDictionary *elementsInfo,
                                                     BOOL *stop) {
         [elementsInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
                                                      UICollectionViewLayoutAttributes *attributes,
                                                      BOOL *innerStop) {
             if(CGRectIntersectsRect(rect, attributes.frame)) {
                 [allAttributes addObject:attributes];
             }
         }];
     }];
     return allAttributes;
 }

 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
 {
     return self.layoutInfo[kPadLayoutType][indexPath];
 }

 # pragma mark _____Private

 - (CGRect)frameForPadAtIndexPath:(NSIndexPath *)indexPath
 {
     NSInteger row = indexPath.section/ self.numberOfColumns;
     NSInteger column = indexPath.section % self.numberOfColumns;

     CGFloat spacingX = self.collectionView.bounds.size.width - self.itemInsets.left - self.itemInsets.right - (self.numberOfColumns * self.itemSize.width);

     if(self.numberOfColumns > 1) spacingX = spacingX / (self.numberOfColumns - 1);

     CGFloat originX = floorf(self.itemInsets.left + (self.itemSize.width + spacingX) * column);

     CGFloat originY = floor(self.itemInsets.top + (self.itemSize.height + self.interItemSpacingY) * row);

     return CGRectMake(originX, originY, self.itemSize.width, self.itemSize.height);
 } 

各セッターでレイアウトを無効にします。

UIViewController 内で collectionView を使用しています viewController で、viewDidLoad で使用するために Cell クラスを登録し、以下をセットアップします。

 # pragma mark - UICollectionViewDataSource

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

 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
 {
     return 1;
 }

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
 {
     Pad *myPad = [collectionView dequeueReusableCellWithReuseIdentifier:kPadLayoutType forIndexPath:indexPath];
     return myPad;
 }
4

1 に答える 1

1

あなたのframeForPadAtIndexPath:メソッドは、同じセクション内の各アイテムに対して同じフレームを返し、セクションの位置だけを変えるようです。

変化

 NSInteger row = indexPath.section/ self.numberOfColumns;
 NSInteger column = indexPath.section % self.numberOfColumns;

の中へ

 NSInteger row = indexPath.item/ self.numberOfColumns;
 NSInteger column = indexPath.item % self.numberOfColumns;

より良い結果が得られる可能性があります。

于 2013-07-17T15:47:37.390 に答える