哪种方法更好/更清洁?

时间:2013-02-07 11:01:46

标签: objective-c uitableview

循环播放

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {}

方法我将数据设置为我的自定义单元格(图像和文本)。我想知道实现这一目标的最佳途径是什么。

我可以使用2个不同的数组(图像数组和文本数组),并执行以下操作:

cell.image setImage: //get image from imageArray with indexPath.row
cell.text.text = [textArray objectAtIndex:indexPath.row];

或使用像这样的多维数组:

cell.image setImage: [imageArray objectAtIndex:indexPath.row] objectAtIndex:0;
cell.text.text = [textArray objectAtIndex:indexPath.row] objectAtIndex:1;

// or use of dictionary with keys

哪种方法更快或更易读?

3 个答案:

答案 0 :(得分:2)

我个人认为以下是最干净的解决方案:

  • 为数组中的项创建模型。
  • 创建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;
}

这是我认为最干净的解决方案和我大部分时间采用的方法。我喜欢让我的视图控制器很小。我也喜欢这样一个事实,即我的视图控制器不必知道我的(自定义)表视图单元格具有哪些控件。表视图单元格负责如何根据提供的数据绘制自己。

答案 1 :(得分:1)

我会添加一个简单的数据类,并将类实例放在NSArray中。或者使用NSArray NSDictionary@interface DisplayItems : NSObject @property (nonatomic, strong) NSString *text; @property (nonatomic, strong) UIImage *image; @end @implementation DisplayItems @end 个对象,这样就可以按名称来处理这些项目,而不是位置。

示例类代码(这些天类很容易):

{{1}}

答案 2 :(得分:1)

一个想法是创建一个自定义类:

@interface CellInfo : NSObject
@property (....) UIImage *image;
@property (....) NSString *text;
@end

然后:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
...
    CellInfo *info = [self.cellInfoArray objectAtIndex:indexPath.row];
    cell.image = info.image;
    cell.text = info.text;
...
}