1

ループしている間

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

カスタムセル(画像とテキスト)にデータを設定するメソッドim。これを達成するための最良の方法は何だろうと思っていました。

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

どの方法がより速く、より読みやすくなっていますか?

4

3 に答える 3

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;
}

これは私の意見では、最もクリーンなソリューションであり、私がほとんどの場合採用しているアプローチです。ビューコントローラを小さく保つのが好きです。また、ビューコントローラーが(カスタム)テーブルビューセルのコントロールを知る必要がないという事実も気に入っています。テーブルビューセルは、提供されたデータに応じて、それ自体を描画する方法について全責任を負います。

于 2013-02-07T11:30:20.773 に答える
1

単純なデータクラスを追加し、クラスインスタンスをに配置しますNSArray。またはNSArrayNSDictionaryオブジェクトのを使用して、アイテムを位置ではなく名前でアドレス指定できるようにします。

クラスコードの例(最近のクラスは非常に簡単です):

@interface DisplayItems : NSObject
@property (nonatomic, strong) NSString *text;
@property (nonatomic, strong) UIImage *image;
@end

@implementation DisplayItems
@end
于 2013-02-07T11:11:34.400 に答える
1

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;
...
}
于 2013-02-07T11:15:09.263 に答える