0

各 tam tableView を異なるデータで表示するために tableView を使用しています。すべての tableView デリゲートを使用してインターフェイスに戻ると*list、前のビューに基づいてデータ (フィールドを含むさまざまな配列) に興味をそそられます

if(select = names )...
  list = myData.Names;
if (select = workers)...
  list = myData.Workers;

等々...

そして、私が使用するテーブルデリゲートで:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [list count];
}

しかし、表のセルのオブジェクトを初期化するときに、セルに適切なオブジェクトを正確に設定するにはどうすればよいですか。今私が使用するハードコード:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];       
    }
    //HARD-CODED
    names *s = [list objectAtIndex:indexPath.row];
    cell.textLabel.text = names.firstName;
    cell.detailTextLabel.text=s.lastName;
    return cell;   
}

を設定するとき、毎回正しいオブジェクトにキャストlistする方法を知るにはどうすればよいですか? workers何百万ものif

たとえば、

  if (select = workers)...
          list = myData.Workers;

[list count] は正しい数値を返しますが、リストに基づいてデータを表示したいのですが、それをキャストして自動的にワーカーを宣言するにはどうすればよいですか

workers *s = [list objectAtIndex:indexPath.row];
4

3 に答える 3

2

私はあなたの問題を理解していると思うので、説明してみましょう:

これはプロトコルを使用して簡単に解決でき、実際のオブジェクトに対するセル構成の責任を与えます。

まず、クラスが準拠するプロトコルを宣言します。

@class MyTableViewCell;

@protocol CellConfiguring

- (void)configureCell:(MyTableViewCell *)cell;

@end

次に、いくつかのクラスを作成し、それらすべてがこのプロトコルに準拠していることを確認します。

@interface Workers : NSObject <CellConfiguring>

@property (retain, nonatomic) NSString *company;
@property (retain, nonatomic) NSString *salary;

@end

と:

@interface Names : NSObject <CellConfiguring>

@property (retain, nonatomic) NSString *firstName;
@property (retain, nonatomic) NSString *lastName;

@end

等...

それらの実装では、それぞれが異なる方法でセルの構成を処理します。

#import "MyTableViewCell.h"

@implementation Workers

- (void)configureCell:(MyTableViewCell *)cell
{
    cell.textLabel.text = self.company;
    cell.detailTextLabel.text = self.salary;
}

@end

と:

#import "MyTableViewCell.h"

@implementation Names

- (void)configureCell:(MyTableViewCell *)cell
{
    cell.textLabel.text = self.firstName;
    cell.detailTextLabel.text = self.lastName;
}

@end

受け取ったセルは、作成したカスタム セルであることを忘れないでください。例えば:

@interface MyTableViewCell : UITableViewCell

@property (retain, nonatomic) UILabel *textLabel;
@property (retain, nonatomic) UILabel *detailTextLabel;

@end

次に、デリゲート呼び出しで:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];       
    }

    id myObject = [list objectAtIndex:indexPath.row];
    if ([myObject conformsToProtocol:@protocol(CellConfiguring)]
        [myObject configureCell:cell];    
    return cell;   
}

以上です。if-else ステートメントやキャストはもう必要ありません。

ヒント: クラス内に if-else ステートメントが多すぎてコードが汚れていることに気付き始めたときはいつでも、責任について考え始めてください。オブジェクトは、セルの構成方法を理解する責任がありますか? それとも、そのタスクを別のオブジェクトに委任できますか?

于 2012-09-01T13:24:38.463 に答える
1

BOOL フラグのように .h ファイルに 1 つのフラグを設定します。フラグに従ってデータが埋められます。

最初にフラグは ViewDidLoad で TRUE になります。

セットリストは次のようになります。

if()...
listNames = myData.Names;
if ()...
listWorkers = myData.Workers;

およびテーブルデリゲートで:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 if(flag){
 return [listNames count];
 else
 {
  return [listWorkers count];
 }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];       
    }
    if(flag)
    {
       names *s = [listNames objectAtIndex:indexPath.row];
       cell.textLabel.text = names.firstName;
       cell.detailTextLabel.text=s.lastName;
       return cell;  
    }
    else
   {
       names *s = [listWorkers objectAtIndex:indexPath.row];
       cell.textLabel.text = names.firstName; // change for listWorkers
       cell.detailTextLabel.text=s.lastName; // change for listWorkers
       return cell;
   } 
}

今、変わりたいと思ったら

flag = FALSE; //worker data will be filled
[tableView reloadData]
于 2012-09-01T13:09:17.420 に答える
0

次の解決策を使用できる場合があります...

オブジェクトの種類ごとに UITableViewDataSource に準拠するカスタム オブジェクトを作成します。たとえば、WorkerDataSource、NamesDataSource など...

表示するデータに応じて、tableView に適切な dataSource を設定します。私が取り組んでいるプロジェクトの例...

#define SECTION_HEADER_HEIGHT 20.0f


@interface FSMatchProgrammeDataSource ()

@property (nonatomic, copy) NSArray *matches;
@property (nonatomic, copy) NSArray *groupedMatches;

@end


@implementation FSMatchProgrammeDataSource

@synthesize matches               = _matches;
@synthesize groupedMatches        = _groupedMatches;
@synthesize didSelectMatchHandler = _didSelectMatchHandler;

+ (FSMatchProgrammeDataSource *)dataSourceWithMatches:(NSArray *)matches
{
    FSMatchProgrammeDataSource *dataSource = [[FSMatchProgrammeDataSource alloc] init];
    if (dataSource)
    {
        dataSource.matches = matches;
    }
    return dataSource;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return _groupedMatches.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSArray *matches = [_groupedMatches objectAtIndex:section];
    return matches.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"MatchProgrammeCellIdentifier";

    FSMatchProgrammeCell *cell = (FSMatchProgrammeCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell)
    {
        cell = [[FSMatchProgrammeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];        
    }

    NSArray *matches = [_groupedMatches objectAtIndex:indexPath.section];
    cell.match = [matches objectAtIndex:indexPath.row];

    DLog(@"%@", cell.match);

    return cell;
}

#pragma mark - Table view delegate

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
   // custom view created here ...
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return SECTION_HEADER_HEIGHT;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44.0f;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (_didSelectMatchHandler)
    {
        NSArray *matches = [_groupedMatches objectAtIndex:indexPath.section];
        FSMatch *match   = [matches objectAtIndex:indexPath.row];

        _didSelectMatchHandler(match);
    }
}

#pragma mark - Properties

- (void)setMatches:(NSArray *)matches
{
    // matches property set, also an sorted / grouped copy is created for display called groupMatches ...
}

@end

そして、dataSource は次のように tableViewController に割り当てられます。

- (void)refreshView
{
    BOOL showInfoLabel = NO;

    switch (_tabBar.selectedSegmentTag)
    {
        case TabProgramme:
            _tableView.dataSource = _programmeDataSource;
            _tableView.delegate   = _programmeDataSource;
            break;
        case TabResults: 
            _tableView.dataSource = _resultsDataSource;
            _tableView.delegate   = _resultsDataSource;
            break;
        case TabStandings:
            _tableView.dataSource = _standingsDataSource;
            _tableView.delegate   = _standingsDataSource;
            break;
        default: break;
    }

    [self.tableView reloadData];
}
于 2012-09-01T13:58:23.267 に答える