I have a TableView
with 3 UILabel
: title, author name and category and a UIImage
. All cells should look similar to this layout:
Correct cell layout:
When the app starts for some reason some cells have the title UILabel
alignment not as it should be:
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.