2014-03-31 12 views
0

在畫面中的問題時消失:的UITableView跳過自定義的UITableViewCell中的每一個之間的一個indexPath,滾動

enter image description here

基本上,我的表視圖增加​​相互之間的空單元格,我不知道爲什麼。我已經嘗試在cellForRowAtIndexPath:willDisplayCell:forRowAtIndexPath:didSelectRowAtIndexPath:中放入NSLog聲明,並且每個單元的indexPath中的數據源都是正確的。只是顯示的單元格正在跳過,我不明白爲什麼。

我的視圖控制器和表視圖單元格子類也非常簡單。下面的代碼:

PrivateMessagesViewController.m

static NSString * const kCellIdentifier = @"kCellIdentifier"; 

@interface PrivateMessagesViewController() <UITableViewDataSource, UITableViewDelegate> 

@property (strong, nonatomic) NSMutableArray *messages; 
@property (strong, nonatomic) SCPFInboxQuery *query; 
@property (nonatomic) BOOL hasAlreadyFetchedBefore; 

@property (strong, nonatomic) UITableView *tableView; 

// This is a custom view that either shows a loading animation, 
// a "No Results Found" label, or an error message with a Retry button 
// at the center of the view of a view controller. 
@property (strong, nonatomic) SCPCenterView *centerView; 

@end 

@implementation PrivateMessagesViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.title = @"Private Messages"; 

    self.messages = [NSMutableArray array]; 
    self.query = [[SCPFInboxQuery alloc] init]; 

    self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, [UIScreen mainScreen].bounds.size.height - 113) style:UITableViewStylePlain]; 
    self.tableView.dataSource = self; 
    self.tableView.delegate = self; 
    [self.tableView registerClass:[SCPPrivateMessageListCell class] forCellReuseIdentifier:kCellIdentifier]; 
    self.tableView.alpha = 0; // The table view starts out invisible. 
    [self.view addSubview:self.tableView]; 
} 

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

    if (!self.hasAlreadyFetchedBefore) { 
     [self.view addSubview:self.centerView]; 
     [self.centerView showLoadingView]; 

     __weak PrivateMessagesViewController *weakSelf = self; 
     [self.query runInBackgroundWithCompletion:^(NSArray *messages, NSError *error) { 
      PrivateMessagesViewController *innerSelf = weakSelf; 

      // If there is an error, handle it. 
      if (error) { 
       // ... 
       return; 
      } 

      // If there weren't any messages before and none were found, 
      // the user has no messages in the inbox. 
      if (!innerSelf.hasAlreadyFetchedBefore && messages.count == 0) { 
       [innerSelf.centerView showNoResultsLabel]; 
      } 

      else { 
       if (!innerSelf.hasAlreadyFetchedBefore) { 
        [innerSelf.centerView fadeOutAndRemoveFromSuperview]; 
        innerSelf.tableView.alpha = 1; 
       } else { 
       } 
       [innerSelf.messages addObjectsFromArray:messages]; 
       [innerSelf.tableView reloadData]; 
      } 

      innerSelf.hasAlreadyFetchedBefore = YES; 
     }]; 
    } 
} 

#pragma mark - Table view data source 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return self.messages.count; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    SCPPrivateMessageListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; 
    SCPFMessage *message = self.messages[indexPath.row]; 
    cell.message = message; 
    return cell; 
} 

#pragma mark - Table view delegate 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return [SCPPrivateMessageListCell heightForMessage:self.messages[indexPath.row]]; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    SCPPrivateMessageListCell *theCell = (SCPPrivateMessageListCell *)cell; 
    NSLog(@"Message at %d: %@", indexPath.row, theCell.message.rawData); 
} 

#pragma mark - Getters 

- (SCPCenterView *)centerView 
{ 
    if (!_centerView) { 
     _centerView = [[SCPCenterView alloc] initWithParent:self.view]; 
     _centerView.noResultsText = @"You don't have any private messages yet."; 
    } 
    return _centerView; 
} 

@end 

SCPPrivateMessageListCell.m

static const CGFloat kInnerMargin = 10; 
static const CGFloat kSpaceBetweenImageAndRightLabel = 10; 
static const CGFloat kImageViewSize = 60; 
static const CGFloat kRightLabelX = kInnerMargin + kImageViewSize + kSpaceBetweenImageAndRightLabel; 
static const CGFloat kMaxRightLabelWidth = 320 - (kRightLabelX + kInnerMargin); 

@interface SCPPrivateMessageListCell() 

@property (strong, nonatomic) UIImageView *thumbnailImageView; 
@property (strong, nonatomic) UILabel *dateLabel; 
@property (strong, nonatomic) UILabel *senderLabel; 
@property (strong, nonatomic) UILabel *subjectLabel; 
@property (strong, nonatomic) UILabel *summaryLabel; 

@end 

@implementation SCPPrivateMessageListCell 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     _thumbnailImageView = [[UIImageView alloc] init]; 
     _thumbnailImageView.contentMode = UIViewContentModeScaleAspectFill; 
     _thumbnailImageView.layer.cornerRadius = kImageViewSize/2; 
     _thumbnailImageView.clipsToBounds = YES; 

     _dateLabel = [[UILabel alloc] init]; 
     _dateLabel.font = [UIFont systemFontOfSize:10]; 
     _dateLabel.textAlignment = NSTextAlignmentCenter; 
     _dateLabel.numberOfLines = 1; 
     _dateLabel.lineBreakMode = NSLineBreakByTruncatingTail; 

     _senderLabel = [SCPPrivateMessageListCell senderLabel]; 
     _subjectLabel = [SCPPrivateMessageListCell subjectLabel]; 
     _summaryLabel = [SCPPrivateMessageListCell summaryLabel]; 

     [self.contentView addSubview:_thumbnailImageView]; 
     [self.contentView addSubview:_dateLabel]; 
     [self.contentView addSubview:_senderLabel]; 
     [self.contentView addSubview:_subjectLabel]; 
     [self.contentView addSubview:_summaryLabel]; 
    } 
    return self; 
} 

- (void)setMessage:(SCPFMessage *)message 
{ 
    _message = message; 

    [self.thumbnailImageView setImageWithURL:message.thumbnailURL]; 
    self.dateLabel.text = message.dateSent; 
    self.senderLabel.text = message.nameOfSender; 
    self.subjectLabel.text = message.subject; 
    self.summaryLabel.text = message.summary; 

    [self setNeedsLayout]; 
} 

- (void)layoutSubviews 
{ 
    self.thumbnailImageView.frame = CGRectMake(kInnerMargin, kInnerMargin, kImageViewSize, kImageViewSize); 

    [self.dateLabel sizeToFitWidth:kImageViewSize]; 
    self.dateLabel.frame = CGRectMake(kInnerMargin, kInnerMargin + kImageViewSize, kImageViewSize, self.dateLabel.frame.size.height); 

    [self.senderLabel sizeToFitWidth:kMaxRightLabelWidth]; 
    self.senderLabel.frame = CGRectMake(kRightLabelX, kInnerMargin, kMaxRightLabelWidth, self.senderLabel.frame.size.height); 

    CGFloat subjectLabelY = self.senderLabel.frame.origin.y + self.senderLabel.frame.size.height; 
    [self.subjectLabel sizeToFitWidth:kMaxRightLabelWidth]; 
    self.subjectLabel.frame = CGRectMake(kRightLabelX, subjectLabelY, kMaxRightLabelWidth, self.subjectLabel.frame.size.height); 

    CGFloat summaryLabelY = self.subjectLabel.frame.origin.y + self.subjectLabel.frame.size.height; 
    [self.summaryLabel sizeToFitWidth:kMaxRightLabelWidth]; 
    self.summaryLabel.frame = CGRectMake(kRightLabelX, summaryLabelY, kMaxRightLabelWidth, self.summaryLabel.frame.size.height); 

    CGFloat cellHeight = [SCPPrivateMessageListCell heightForMessage:self.message]; 
    self.contentView.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, cellHeight); 
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, cellHeight); 
} 

#pragma mark - Class methods 

+ (UILabel *)senderLabel 
{ 
    UILabel *label = [[UILabel alloc] init]; 
    label.font = [UIFont boldSystemFontOfSize:17]; 
    label.textColor = [UIColor colorFromHex:0x0076be]; 
    label.numberOfLines = 1; 
    label.lineBreakMode = NSLineBreakByTruncatingTail; 
    return label; 
} 

+ (UILabel *)subjectLabel 
{ 
    UILabel *label = [[UILabel alloc] init]; 
    label.font = [UIFont systemFontOfSize:14]; 
    label.numberOfLines = 1; 
    label.lineBreakMode = NSLineBreakByTruncatingTail; 
    return label; 
} 

+ (UILabel *)summaryLabel 
{ 
    UILabel *label = [[UILabel alloc] init]; 
    label.font = [UIFont systemFontOfSize:12]; 
    label.textColor = [UIColor grayColor]; 
    label.numberOfLines = 3; 
    label.lineBreakMode = NSLineBreakByTruncatingTail; 
    return label; 
} 

+ (CGFloat)heightForMessage:(SCPFMessage *)message 
{ 
    CGFloat height = kInnerMargin; 

    UILabel *senderLabel = [SCPPrivateMessageListCell senderLabel]; 
    senderLabel.text = message.nameOfSender; 
    [senderLabel sizeToFitWidth:kMaxRightLabelWidth]; 
    height += senderLabel.frame.size.height; 

    UILabel *subjectLabel = [SCPPrivateMessageListCell subjectLabel]; 
    subjectLabel.text = message.subject; 
    [subjectLabel sizeToFitWidth:kMaxRightLabelWidth]; 
    height += subjectLabel.frame.size.height; 

    UILabel *summaryLabel = [SCPPrivateMessageListCell summaryLabel]; 
    summaryLabel.text = message.summary; 
    [summaryLabel sizeToFitWidth:kMaxRightLabelWidth]; 
    height += summaryLabel.frame.size.height; 

    height += kInnerMargin; 

    return height; 
} 

@end 

有。我沒有做任何非標準的事情。當我滾動時,單元格的子視圖也會消失,但是當我將它們滾動回來時,內容會顯示出來,仍然會跳過空單元格。任何人都知道爲什麼會發生這種情況?

+0

我不確定,但如果初始化與reuseIdentifier失敗,可能是您從未初始化單元格。 – saurabh

回答

0

問題出在我的表格視圖單元的layoutSubviews

self.contentView.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, cellHeight); 

本來應該:

self.contentView.frame = CGRectMake(self.contentView.frame.origin.x, self.contentView.frame.origin.y, self.contentView.frame.size.width, cellHeight); 

我發現從init方法內部設置不同的顏色self.backgroundColorself.contentView.backgroundColor

相關問題