Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView cell width on iOS 8 stuck at 320pt

I am currently trying to create a simple UITableView with custom cells without using storyboard.

I'm getting an issue on the iPhone 6 simulator where the table view has a width of 375 (as it should), but the cells inside are getting a width of 320.

The number 320 is nowhere to be found in the project as I am not hard coding it. When I am setting the background colour of the cell, it extends the full width of 375, but I need to align an image to the right, which only aligns 320 across as shown in the photo below.

image of weird tableviewcell sizing

I'm not sure if it's because I'm missing constraints or if there's a bug. Any help is appreciated, thanks!

Code to set up table:

- (TBMessageViewCell *)getMessageCellforTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath
{

    static NSString *cellIdentifier = @"MessageCell";
    TBMessageViewCell *cell = (TBMessageViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[TBMessageViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        [cell createSubviews];
    }

     // Set the new message and refresh
    [cell setMessage:self.viewModel.messages[indexPath.row]];
    [cell populateSubviews];
    cell.backgroundColor = [UIColor blueColor];

    NSLog(@"cell Width: %f", cell.contentView.frame.size.width);

    return cell;
}

Complete TBMessageViewCell:

@implementation TBMessageViewCell

const CGFloat MARGIN = 10.0f;
const CGFloat AVATAR_SIZE = 40.0f;

-(id)initWithStyle:(UITableViewCellStyle *)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if(self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]){
    }

// Sets background and selected background color
self.backgroundColor = [UIColor clearColor];
UIView *selectionColor = [[UIView alloc] init];
selectionColor.backgroundColor = [UIColor clearColor];
self.selectedBackgroundView = selectionColor;

return self;
}

- (void)populateSubviews
{
    // Set the message body
    [self.messageBodyLabel setText:self.message.body];
    [self.messageBodyLabel setTextAlignment:NSTextAlignmentRight];
    CGRect bodyFrame = CGRectMake(MARGIN, MARGIN, self.frame.size.width - (AVATAR_SIZE + (MARGIN * 3)), self.frame.size.height);
    // Calculates the expected frame size based on the font and dimensions of the label
    // FLT_MAX simply means no constraint in height
    CGSize maximumLabelSize = CGSizeMake(bodyFrame.size.width, FLT_MAX);
    CGRect textRect = [self.message.body boundingRectWithSize:maximumLabelSize
    options:NSStringDrawingUsesLineFragmentOrigin
    attributes:@{NSFontAttributeName:self.messageBodyLabel.font}
    context:nil];
    bodyFrame.size.height = textRect.size.height;

    // Setup the new avatar frame (Right aligned)
    CGRect avatarFrame = CGRectMake(bodyFrame.size.width + (MARGIN * 2), MARGIN, AVATAR_SIZE, AVATAR_SIZE);

    // Align to the LEFT side for current user's messages
    if ([[TBConfig userID] isEqualToString:self.message.user.userID]) {
        // Set avatar to left if it's me
        avatarFrame.origin.x = MARGIN;
        bodyFrame.origin.x = AVATAR_SIZE + (MARGIN * 2);
        [self.messageBodyLabel setTextAlignment:NSTextAlignmentLeft];
    }

    self.avatar.frame = avatarFrame;
    self.avatar.layer.cornerRadius = self.avatar.frame.size.width/2;
    self.messageBodyLabel.frame = bodyFrame;

    // Set the new cell height on the main Cell
    CGFloat cellHeight = MAX(bodyFrame.size.height, self.frame.size.height) + MARGIN;
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, cellHeight);

    // Set the new Profile avatar
    if (![self.avatar.profileID isEqualToString:self.message.user.facebookID]) {
        [self.avatar setProfileID:nil];
        [self.avatar setProfileID:self.message.user.facebookID];
    }
}

- (void)createSubviews
{
    self.messageBodyLabel = [[UILabel alloc] init];
    self.messageBodyLabel.textColor = [UIColor whiteColor];
    self.messageBodyLabel.lineBreakMode = NSLineBreakByWordWrapping;
    self.messageBodyLabel.numberOfLines = 0;
    [self addSubview:self.messageBodyLabel];

    // Creates the avatar
    self.avatar = [[FBProfilePictureView alloc] init];
    [self.avatar setPictureCropping:FBProfilePictureCroppingSquare];
    [self addSubview:self.avatar];
}
like image 221
Matt Welson Avatar asked Oct 15 '14 01:10

Matt Welson


2 Answers

You're printing the size of the cell before it has been added to the display — before it has been sized. It doesn't yet know the size of tableview it will be added to.

The cells will be given an appropriate frame when added to the display.

EDIT: oh, and you probably don't want that cellIdentifier to be static. You probably wanted *const.

like image 176
Tommy Avatar answered Sep 20 '22 14:09

Tommy


Don't know if you have found the answer. I faced the same problem when I was trying to subclass UITableViewCell and add custom subviews programmatically without using xib.

Finally the solution worked for me is to use [[UIScreen mainScreen] applicationFrame] instead of self.frame when calculating subviews' frames.

like image 38
Jin Avatar answered Sep 19 '22 14:09

Jin