Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TableView UILabel alignment changes when scrolling

I have a TableView with 3 UILabel: title, author name and category and a UIImage. All cells should look similar to this layout:

Cell Layout

Correct cell layout:

Proper Label Alignment

When the app starts for some reason some cells have the title UILabel alignment not as it should be:

Incorrect title label alignment

Incorrect title label alignment

After scrolling the TableView a few times, these cells end up with the proper alignment. I'm not quite sure what is causing this.

I have created a Custom TableView Cell class (followed this tutorial)

CustomTableViewCell.h

@interface CustomTableViewCell : UITableViewCell
@property (nonatomic, weak) IBOutlet UIImageView *image;
@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) IBOutlet UILabel *authorLabel;
@property (nonatomic, weak) IBOutlet UILabel *categoryLabel;
@end

CustomTableViewCell.m

@implementation CustomTableViewCell

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

    if (self) {
        // Initialization code
    }
    return self;
}

- (void)awakeFromNib
{
   // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    [self.contentView layoutIfNeeded];
    self.titleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.titleLabel.frame);
    [self.titleLabel sizeToFit];
    [self.titleLabel setNumberOfLines:0];
}

@end

This is how this class is implemented in the ViewController:

@interface CurrentIssueViewController () {
    CurrentIssueModel *_currentIssueModel;
    Article *_selectedArticle;
}

@end

@implementation CurrentIssueViewController

static NSString *cellIdentifier = @"BasicCell";
UIActivityIndicatorView *activityView;
//@synthesize _feedItems;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];


    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangePreferredContentSize:)name:UIContentSizeCategoryDidChangeNotification object:nil];

    // Create array object and assign it to _feedItems variable
    self._feedItems = [[NSArray alloc] init];

    // Create new HomeModel object and assign it to _homeModel variable
    _currentIssueModel = [[CurrentIssueModel alloc] init];

    // Set this view controller object as the delegate for the home model object
    _currentIssueModel.delegate = self;

    // Call the download items method of the home model object
    [_currentIssueModel downloadItems];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil];
}

- (void)didChangePreferredContentSize:(NSNotification *)notification
{
    [self.tableView reloadData];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)itemsDownloaded:(NSArray *)items
{
    // This delegate method will get called when the items are finished downloading

    // Set the downloaded items to the array
    self._feedItems = items;

    [activityView stopAnimating];

    // Reload the table view
    [self.tableView reloadData];
}

#pragma mark Table View Delegate Methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of feed items (initially 0)
    return self._feedItems.count;
}

/* ================================================== */

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    [self configureCell:cell forRowAtIndexPath:indexPath];
    return cell;
}

- (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell isKindOfClass:[CustomTableViewCell class]])
    {
        CustomTableViewCell *textCell = (CustomTableViewCell *)cell;

        Article *article_item = self._feedItems[indexPath.row];

        NSString *fulltitle = article_item.Title;

        if (article_item.Subtitle != nil && article_item.Subtitle.length != 0) {
            fulltitle = [fulltitle stringByAppendingString:@": "];
            fulltitle = [fulltitle stringByAppendingString:article_item.Subtitle];
        }
        textCell.titleLabel.text = fulltitle;

        if ([article_item.Author isEqualToString:@"accountant"]) {
            textCell.authorLabel.text = @"";
        }
        else {
            textCell.authorLabel.text = article_item.Author;
        }

        textCell.categoryLabel.text = article_item.Cat_Name;

        textCell.titleLabel.numberOfLines = 0;
        textCell.titleLabel.font = [UIFont fontWithName:@"Arial" size:12.0f];

        textCell.authorLabel.font = [UIFont fontWithName:@"Arial" size:10.0f];
        textCell.categoryLabel.font = [UIFont fontWithName:@"Arial" size:10.0f];
        textCell.categoryLabel.textAlignment = NSTextAlignmentRight;

        NSURL *url;

        if ([article_item.ImageUrl length] != 0) {
            url = [NSURL URLWithString:article_item.ImageUrl];
        }
        else {
            url = [NSURL URLWithString:@"imageurl"];
        }

        [textCell.image sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"default_image.jpg"]];
    }
}

- (CustomTableViewCell *)prototypeCell
{
    if (!_prototypeCell)
    {
        _prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    }
    return _prototypeCell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self configureCell:self.prototypeCell forRowAtIndexPath:indexPath];

    self.prototypeCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.bounds), CGRectGetHeight(self.prototypeCell.bounds));

    [self.prototypeCell layoutIfNeeded];

    CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size.height+1;
}

/* ================================================== */

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Set selected article to var
    _selectedArticle = self._feedItems[indexPath.row];
    [self performSegueWithIdentifier:@"detailSegue" sender:self];

}

#pragma mark Segue

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get reference to the destination view controller
    ArticleViewController *articleVC = segue.destinationViewController;

    // Set the property to the selected article so when the view for
    // detail view controller loads, it can access that property to get the feeditem obj
    articleVC.selectedArticle = _selectedArticle;
}

@end

I guess it's something to do with forRowAtIndexPath but I can't really figure out what's the issue.

Update:

I noticed that there is another problem with the title UILabel. Whenever you select a cell, view the article in another ViewController and go back to the UITableView the title labels are positioned in the Center Left rather than Top Left. Once you scroll again the title labels adjust to the proper position.

like image 570
j.grima Avatar asked Apr 28 '26 20:04

j.grima


1 Answers

You have auto layout selected for the NIB/Storyboard but have not added any constraints to your cells. Add layout constraints to your cells. There is a great answer here that explains it in some details:

like image 113
Rog Avatar answered May 01 '26 11:05

Rog



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!