web-dev-qa-db-ja.com

動的な高さのUICollectionViewがセル間で同じスペースを取得していません

私は同様の問題を抱えています このように

実行時にビューの高さを生成しています。これが私のコードです

@interface CollectionViewController ()
{
    NSMutableArray *arrMain;
}
@property(nonatomic,strong) NSMutableArray *arrMain;
@end

@implementation CollectionViewController
@synthesize arrMain,


- (void)viewDidLoad
{
    [super viewDidLoad];

    [cView registerNib:[UINib nibWithNibName:@"CViewCell" bundle:nil] forCellWithReuseIdentifier:kCellID];

    CViewFlowLayout *fl = [[CViewFlowLayout alloc] init];
    self.cView.collectionViewLayout = fl;

    NSString *strJson = MY FUNCTION WHICH RETURNS JSON STRING;
    SBJSON *parser = [[SBJSON alloc] init];

    self.arrMain = [[NSMutableArray alloc] init];
    self.arrMain = [parser objectWithString:strJson error:nil];
    for (int i=0; i<[self.arrMain count]; i++) {
        NSDictionary *dic = [self.arrMain objectAtIndex:i];
        [self setTags:[[UIView alloc] init] selDictionary:dic];  // This function generates height and save it to the dictionary
    }
    [cView reloadData];
}

- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section;
{
    return [self.arrMain count];
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{

    NSDictionary *dic = [self.arrMain objectAtIndex:indexPath.row];
    return CGSizeMake(236,40+[[dic valueForKey:@"TAGS_HEIGHT"] intValue]);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{

    CViewCell *cell =(CViewCell *) [cv dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
    NSDictionary *dic = [self.arrMain objectAtIndex:indexPath.row];
    if ([cell viewWithTag:11]){
        [[cell viewWithTag:11] release];
        [[cell viewWithTag:11] removeFromSuperview];
    }
    UIView *viewTags = [[UIView alloc] init];
    [viewTags setTag:11];
    [viewTags setBackgroundColor:[UIColor lightGrayColor]];
    [self setTags:viewTags selDictionary:dic];
    [viewTags setFrame:CGRectMake(5, 10, CONTENT_WIDTH, [[dic valueForKey:@"TAGS_HEIGHT"] floatValue])];
    [cell.contentView addSubview:viewTags];

    return cell;
}

上記のリンクソリューションを試しましたが、機能しません。これが私の出力の画像です。

間隔を同じにする必要があります。この問題の解決策を持っている人はいますか?

このUICOllectionViewのバグですか?この問題は この記事 でも見つかりました。

11
Viral Narshana

私はこの種の問題の一般的な解決策を持っています:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [cView registerNib:[UINib nibWithNibName:@"CViewCell" bundle:nil] forCellWithReuseIdentifier:kCellID];

    CViewFlowLayout *fl = [[CViewFlowLayout alloc] init];
    fl.minimumInteritemSpacing = 10;
    fl.scrollDirection = UICollectionViewScrollDirectionVertical;
    self.cView.collectionViewLayout = fl;

    NSString *strJson = MY FUNCTION WHICH RETURNS JSON STRING;
    SBJSON *parser = [[SBJSON alloc] init];

    self.arrMain = [[NSMutableArray alloc] init];
    self.arrMain = [parser objectWithString:strJson error:nil];
    for (int i=0; i<[self.arrMain count]; i++) {
    NSDictionary *dic = [self.arrMain objectAtIndex:i];
    [self setTags:[[UIView alloc] init] selDictionary:dic];  // This function generates height and save it to the dictionary
}
    [cView reloadData];

}

次に、UICollectionViewFlowLayoutのサブクラスであるCViewFlowLayout.mのコードを更新します。

コードは次のとおりです。

#define numColumns 3
@implementation CViewFlowLayout
@synthesize numOfColumnsToDisplay;
- (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];

    if (indexPath.item < numColumns){
        CGRect f = currentItemAttributes.frame;
        f.Origin.y = 0;
        currentItemAttributes.frame = f;
        return currentItemAttributes;
    }
    NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-numColumns inSection:indexPath.section];
    CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame;
    CGFloat YPointNew = fPrev.Origin.y + fPrev.size.height + 10;
    CGRect f = currentItemAttributes.frame;
    f.Origin.y = YPointNew;
    currentItemAttributes.frame = f;
    return currentItemAttributes;
}

このソリューションは、垂直スクロールでのみ機能します。多かれ少なかれ列を表示したい場合は、numColumnsを変更するだけです。

7
Viral Narshana

これを試して:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{

    return CGSizeMake(250, 150);
}
3

UICollectionViewFlowLayoutから継承したクラスには、メソッドが含まれている必要があります。

- (CGSize)collectionViewContentSize
{
    return CGSizeMake(200, 200) // as per your cell size
}

- (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];

    if (!currentItemAttributes)
    {
        currentItemAttributes = [UICollectionViewLayoutAttributes
                                 layoutAttributesForCellWithIndexPath:indexPath];
    }
    return currentItemAttributes;
}

そして、CollectionViewControllerに追加します

#pragma mark - Collection View Datasource

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout  *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    // Adjust cell size for orientation
    if (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))
    {
        return CGSizeMake(150, 230);
    }
    return CGSizeMake(150, 230);
}
1
Swati

プロパティを使用してサイズを設定できます。

flowLayout.headerReferenceSize = CGSizeMake(0, 100);//constant height for all the items header

動的な場合:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
    if (section == albumSection) {
        return CGSizeMake(0, 100);
    }

    return CGSizeZero;
}
1
Kumar KL

 enter image description here

1
Muralikrishna

以下の方法で

//迅速

func collectionView(_ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{
 return CGSizeMake(250, 150);
}

// Objective C

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(250, 150);
}
1
Sankalp S Raul