为 tableView 单元格投射到正确的对象
Posted
技术标签:
【中文标题】为 tableView 单元格投射到正确的对象【英文标题】:Casting to right object for tableView cells 【发布时间】:2012-09-01 12:49:30 【问题描述】:我正在使用 tableView 来显示每个带有不同数据的 tam 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];
【问题讨论】:
你到底为什么要投? 单元格的对象,在示例中我使用名称 *s,但如果我将列表设置为工人,我需要将其设置为工人 *s 以使用工人字段 无法追踪问题..你能解释清楚..什么是列表,名称.. 你能举例说明工人以外的其他类是什么样的吗?它们是否都共享相同的界面,意思是:它们都具有@property 姓氏、名字等吗? @pmd 我编辑了这个问题,但不,这就是问题所在,名字有:lastName,FirstName... Workers:salary,company... 【参考方案1】:我想我理解你的问题,所以让我试着解释一下:
这可以使用协议轻松解决,并将单元配置责任交给实际对象。
首先,声明你的类将遵循的协议:
@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 语句、弄脏您的代码时,请开始考虑责任。对象是否应该负责弄清楚如何配置单元?或者我们可以将该任务委托给另一个对象吗?
【讨论】:
,听起来是正确的解决方案,一件事......我在一个新接口中创建了协议,但是当我在每个类中实现协议时,他们无法识别@987654328 @ 你需要一个具有这样标签的 UITableViewCell 子类。例如 MyTableViewCell,然后只需 #import "MyTableViewCell.h"。我以为你已经有一个自定义的 UITableViewCell。让我更新一下我的问题。 抱歉无法理解...我正在 MyTable 界面中创建表格。我用这个代码创建了一个新协议:@class Mytable; @protocol CellConfig -(void)configCell: (MyTable *) cell
,但是当我在每个类上实现它时,我的钢没有textLabel
。
改用 cell.titleLabel.text【参考方案2】:
在 .h 文件中设置一个标志,如 BOOL 标志。数据会根据flag填充。
最初标志在 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]
【讨论】:
其实我有超过 20 种类型的对象..所以我想知道如何在没有单元格的所有 if 语句的情况下做到这一点,认为也许有更简单的解决方案,例如一些如何在第一个初始化单元格的 IF 为 20 个不同的对象更换和使用开关盒【参考方案3】:您也许可以使用以下解决方案...
为每种类型的对象创建一个符合 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];
【讨论】:
以上是关于为 tableView 单元格投射到正确的对象的主要内容,如果未能解决你的问题,请参考以下文章