我個人認爲以下是最乾淨的解決方案:
- 爲陣列中的項目創建模型。
- 創建一個UITableViewCell子類以在單元格中顯示模型。子類將擁有一個接受該模型並在模型更改時自行重繪的屬性。
比方說,我們有一個新聞應用程序。該數組填充了我們爲其創建模型NewsItem的項目。該模型頭部看起來是這樣的:
NewsItem.h
@interface FSNewsItem : NSObject <NSCoding>
@property (nonatomic, copy, readonly) NSString *title;
@property (nonatomic, copy, readonly) NSURL *URL;
@property (nonatomic, copy, readonly) NSString *time;
@property (nonatomic, copy, readonly) NSString *points;
@property (nonatomic, copy, readonly) NSString *author;
// initialiser
+ (FSNewsItem *)newsItemWithTitleNode:(HTMLNode *)node
subTextNode:(HTMLNode *)subNode;
@end
現在對於我們創建一個NewsItemCell細胞。對於NewsItemCell代碼可能類似於以下內容:
NewsItemCell.h
@interface FSNewsItemCell : UITableViewCell
@property (nonatomic, strong) FSNewsItem *newsItem;
@end
NewsItemCell.m
@interface FSNewsCell()
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *detailLabel;
@end
@implementation FSNewsItemCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
self.titleLabel = [[UILabel alloc] init];
[self addSubview:_titleLabel];
self.detailLabel = [[UILabel alloc] init];
[self addSubview:_detailLabel];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
const CGRect bounds = self.bounds;
CGFloat width = bounds.size.width - (FS_FLOAT_PADDING * 2) - 15.0f;
_titleLabel.frame = CGRectMake(FS_FLOAT_PADDING, FS_FLOAT_CELL_PADDING_VERTICAL, width, 20.0f);
CGFloat y = _titleLabel.frame.size.height + (FS_FLOAT_CELL_PADDING_VERTICAL * 2);
_detailLabel.frame = CGRectMake(FS_FLOAT_PADDING, y, width, 15.0f);
}
#pragma mark - Private
- (void)setNewsItem:(FSNewsItem *)newsItem
{
if (_newsItem == newsItem)
{
return;
}
_newsItem = newsItem;
self.titleLabel.text = newsItem.title;
if (_newsItem.points && _newsItem.time)
{
self.detailLabel.text = [NSString stringWithFormat:@"%@ | %@", _newsItem.points, newsItem.time];
}
else
{
self.detailLabel.text = newsItem.time;
}
[self setNeedsLayout];
}
最後,當我們希望顯示在新聞項目我們的代碼如下所示:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
FSNewsItemCell *cell = (FSNewsItemCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[FSNewsItemCell alloc] initWithStyle:UITableViewCellStylePlain reuseIdentifier:CellIdentifier];
}
cell.newsItem = [_items objectAtIndex:indexPath.row];
return cell;
}
這是我認爲最乾淨的解決方案和我大部分時間採取的方法。我喜歡保持我的視圖控制器小。我也喜歡這樣的事實,我的視圖控制器不必知道我的(自定義)表格視圖單元格具有哪些控件。表格視圖單元根據提供的數據對如何繪製自己負全部責任。
如果文本和圖像是密切相關的,也許你應該添加一個類來保存圖像和文本對(例如MyClass)。然後使用MyClass的實例數組,以便獲得更清晰可讀的代碼。 – onevcat
這也是最有效的方法嗎? –
這不能成爲使用課堂的大問題。所有的副作用是你應該創建一些實例。與圖像繪製和文本呈現相比,實例生成和簡單的指針分配將非常便宜。 – onevcat