Ravin Kohli
Ravin Kohli

Reputation: 153

Irregular space between the collectionview cells

I am new to iOS development and this is my first project that i am doing alone. i am trying to show the feed of my college's unofficial fb page using uicollectionview. I have been trying a lot of different things but nothing seems to work. UICollectionViewController.m file

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"DCE Speaks Up";
self.collectionView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1];
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = NO;
NSError *error= nil;

NSURL *feedURL = [NSURL URLWithString:@"https://graph.facebook.com/382057938566656/feed?fields=id,full_picture,message,story,created_time,link&access_token=1750413825187852%7CkUl9nlZFPvdGxGZX4WYabKKG2G4"];

NSData *jsonData = [NSData dataWithContentsOfURL:feedURL];

NSDictionary *dataDictionary= [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.feedArray = [NSMutableArray array];
NSArray *feedTempArray = [dataDictionary objectForKey:@"data"];        //feedTempArray just used for parsing

for (NSDictionary *feedDictionary in feedTempArray) {
    FacebookFeed *fbFeed =[FacebookFeed facebookFeedWithMessage:[feedDictionary objectForKey:@"message"]];
    fbFeed.story = [feedDictionary objectForKey:@"story"];
    fbFeed.imageURL = [NSURL URLWithString:[feedDictionary objectForKey:@"full_picture"]];
    fbFeed.date = [feedDictionary objectForKey:@"created_time"];
    fbFeed.sharedLink = [NSURL URLWithString:[feedDictionary objectForKey:@"link"]];
    [self.feedArray addObject:fbFeed];
}


// Register cell classes
[self.collectionView registerClass:[FacebookCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];

// Do any additional setup after loading the view.
}

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FacebookCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.feed = self.feedArray[indexPath.row];
cell.sizeDictionary = [self sizeForLabelAtIndexPath:indexPath.row collectionView:collectionView];
// Configure the cell
for (UIView *view in cell.contentView.subviews) {
    if ([view isKindOfClass:[UILabel class]]) {
        [view removeFromSuperview];
    }else if ([view isKindOfClass:[UIImageView class]]){
        [view removeFromSuperview];
    }
}
    cell.layer.shouldRasterize = YES;          
    cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
}
#pragma mark <UICollectionViewDelegateFlowLayout>
-(CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    NSDictionary *sizeDictionary = [[NSDictionary alloc] init];
    sizeDictionary = [self sizeForLabelAtIndexPath:indexPath.row collectionView:collectionView];
        return CGSizeMake(self.view.frame.size.width - 20, [sizeDictionary[@"imageHeight"] floatValue] + [sizeDictionary[@"messageHeight"] floatValue] + [sizeDictionary[@"nameHeight"] floatValue]);
}
#pragma mark <UICollectionViewDelegate>
- (NSDictionary *) sizeForLabelAtIndexPath:(NSUInteger)indexPath collectionView:(UICollectionView *)collectionView{
FacebookFeed *feed = self.feedArray[indexPath];
CGSize nameSize = CGSizeFromString(@"DCE Speaks Up");
CGSize imageSize = CGSizeMake(0, 0);
if (feed.imageURL) {
    imageSize = CGSizeMake(470, 394);
}
float height = 80;
NSString *string = @"";
if (feed.message) {
    string = [feed.message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}else if (feed.story){
    string = [feed.story stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
if (string) {
    NSDictionary *attributes = @{
                                 NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody]
                                 };
    CGRect bodyFrame =
    [string boundingRectWithSize:CGSizeMake(CGRectGetWidth(collectionView.bounds),
                                            CGFLOAT_MAX)
                         options:(NSStringDrawingUsesLineFragmentOrigin)
                      attributes:attributes
                         context:nil];

    height += ceilf(CGRectGetHeight(bodyFrame));
}
return @{ @"imageHeight" : @(imageSize.height) , @"messageHeight" : @(height) , @"nameHeight" : @(nameSize.height)};
}

Custom cell file

@implementation FacebookCollectionViewCell

- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self)
{
    self.contentView.backgroundColor = [UIColor whiteColor];
    // change to our custom selected background view
    self.imageView = [[UIImageView alloc] init];
    self.messageLabel = [[UILabel alloc] init];
    self.nameLabel = [[UILabel alloc] init];
}
return self;
}

-(void) setFeed:(FacebookFeed *)feed{
_feed = feed;
self.messageLabel.numberOfLines = 0;
self.messageLabel.lineBreakMode = 0;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSData *data= [NSData dataWithContentsOfURL:feed.imageURL];
    UIImage *theImage=[UIImage imageWithData:data];

    dispatch_async(dispatch_get_main_queue(), ^{
        self.imageView.image= theImage ;
    });
});
if (feed.message) {
    self.messageLabel.text =  [[NSString alloc] initWithString:[feed.message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}else{
    self.messageLabel.text = [[NSString alloc] initWithString:[feed.story stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
self.messageLabel.font = [UIFont fontWithName:@"ArialMT" size:11];
[self.messageLabel sizeToFit];
self.nameLabel.text = @"DCE Speaks Up";
[self.nameLabel setFont:[UIFont fontWithName:@"ArialMT" size:12]];
[self.nameLabel sizeToFit];
}
-(void) layoutSubviews{
NSLog(@"%@",self.feed);
self.nameLabel.frame = CGRectMake(10, 10, self.contentView.bounds.size.width, [self.sizeDictionary[@"nameHeight"] floatValue]);
float height = 200;
if (self.contentView.bounds.size.height - [self.sizeDictionary[@"messageHeight"] floatValue] -[self.sizeDictionary[@"nameHeight"] floatValue] >100) {
    height = self.contentView.bounds.size.height - [self.sizeDictionary[@"messageHeight"] floatValue] -[self.sizeDictionary[@"nameHeight"] floatValue];
}
if (self.feed.imageURL) {
    self.imageView.frame = CGRectMake(10, [self.sizeDictionary[@"messageHeight"] floatValue] +[self.sizeDictionary[@"nameHeight"] floatValue], self.contentView.bounds.size.width - 20,height);
    self.messageLabel.frame = CGRectMake(10, [self.sizeDictionary[@"nameHeight"] floatValue] +10, self.contentView.bounds.size.width - 10, [self.sizeDictionary[@"messageHeight"] floatValue]);

    [self.contentView addSubview:self.messageLabel];
    [self.contentView addSubview:self.imageView];

}else{
    self.messageLabel.frame = CGRectMake(10, [self.sizeDictionary[@"nameHeight"] floatValue], self.contentView.bounds.size.width - 10, [self.sizeDictionary[@"messageHeight"] floatValue]);
    [self.contentView addSubview:self.messageLabel];
}
[self.contentView addSubview:self.nameLabel];

} 
@end

enter image description here enter image description here

Upvotes: 0

Views: 227

Answers (2)

J. Lopes
J. Lopes

Reputation: 1345

I believe your problem is here:

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

    NSDictionary *sizeDictionary = [[NSDictionary alloc] init];
    sizeDictionary = [self sizeForLabelAtIndexPath:indexPath.row collectionView:collectionView];
    return CGSizeMake(self.view.frame.size.width - 20, [sizeDictionary[@"imageHeight"] floatValue] + [sizeDictionary[@"messageHeight"] floatValue] + [sizeDictionary[@"nameHeight"] floatValue]);
}

You set in CGSizeMake width:

self.view.frame.size.width - 20

And height:

[sizeDictionary[@"imageHeight"] floatValue] + [sizeDictionary[@"messageHeight"] floatValue] + [sizeDictionary[@"nameHeight"] floatValue]

Check it out if the size of your height it's correct. It looks like is too big. That method return the size of the each cell. I believe you have been setting a bigger height than you want to.

Upvotes: 0

bsmith11
bsmith11

Reputation: 296

Use NSLayoutConstraints, it's the standard and best practice. Also you shouldn't be adding subviews in layoutSubviews(), as this method may get called multiple times. I'd also suggest moving your cell size calculation code into your UICollectionViewCell subclass.

There is a lot of odd stuff going on in your code, so it's hard to tell what's causing your problems. It's probably a combination of all of the subview adding/removing and manual size calculations. You could also use the visual debugger to give you some clues as to what might be happening: https://www.raywenderlich.com/98356/view-debugging-in-xcode-6

Upvotes: 1

Related Questions