2012-11-01 26 views
81

我试图解决如何在iOS 6中使用UITableView的新方法时设置UITableViewCellStyle使用iOS 6时UITableViewCell的设置风格UITableView dequeueReusableCellWithIdentifier:forIndexPath:

以前,在创建UITableViewCell时,我会更改UITableViewCellStyle枚举,以在调用initWithStyle:时创建不同类型的默认单元格,但从我可以收集的内容中,不再是这种情况。

苹果文档UITableView规定:

返回值: 与相关联的重用标识符一个UITableViewCell对象。此方法始终返回有效的单元格。

讨论: 出于性能原因,一个表视图的数据源通常应该重用的UITableViewCell对象时将其分配细胞在其的tableView行:的cellForRowAtIndexPath:方法。表视图维护数据源标记为可重用的UITableViewCell对象的队列或列表。当被要求提供表格视图的新单元格时,从数据源对象调用此方法。此方法将取出现有单元格(如果有),或根据您之前注册的类或nib文件创建新单元格。

重要:调用此方法之前的方法:你必须注册使用registerNib类或笔尖文件:forCellReuseIdentifier:或的registerClass:forCellReuseIdentifier。

如果您为指定的标识符注册了一个类并且必须创建一个新的单元格,则此方法通过调用其initWithStyle:reuseIdentifier方法来初始化该单元格。对于基于笔尖的单元格,此方法从提供的nib文件加载单元格对象。如果现有单元可供重用,则此方法将调用单元的prepareForReuse方法。

这是我的新cellForRowAtIndexPath看起来如何实施新方法后:

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

    [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier]; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 

    return cell; 
} 

我到目前为止的代码工作正常,但总是返回默认样式。如何更改此设置,以便我可以使用其他样式创建单元格,例如UITableViewCellStyleDefault,UITableViewCellStyleValue1UITableViewCellStyleValue2UITableViewCellStyleSubtitle

我不想要子类UITableViewCell,我只是想改变默认类型,因为我可以在iOS 6之前做。看起来很奇怪的是,苹果会提供增强的方法,但用最少的文档来支持它们的实现。

有没有人掌握了这个,或遇到类似的问题?我努力寻找任何合理的信息。

回答

103

我知道你说你不想创建一个子类,但它看起来不可避免。基于同时在iOS的6.0模拟器测试汇编代码,UITableView通过执行

[[<RegisteredClass> alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:<ReuseIdentifier>] 

换句话说创建的UITableViewCell(或它的子类)的新实例,发送(UITableViewCellStyleDefault)样式似乎硬编码的。为了解决这个问题,你需要创建覆盖缺省初始化initWithStyle:reuseIdentifier:,并传递您希望使用的样式子类:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    // ignore the style argument, use our own to override 
    self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     // If you need any further customization 
    } 
    return self; 
} 

而且,它可能是更好的viewDidLoad发送registerClass:forCellReuseIdentifier:,而不是做它每一个单元被请求时:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.tableView registerClass:<RegisteredClass> forCellReuseIdentifier:<ReuseIdentifier>]; 
} 
+4

我开始认为这确实是这种情况。这不是一个主要的问题,但不得不继承'UITableViewCell'以获得其他默认样式是一件很痛苦的事情,因为它只会产生不必要的文件。感谢您的评论并确认我的怀疑。 – CaptainRedmuff

+11

不要忘记,而不是子类化,你可以使用旧的iOS5方法,这仍然有效。这样你可以初始化你想要的任何类型的单元格样式。见另一个答案。 – SpacyRicochet

60

dequeueReusableCellWithIdentifier不会被弃用这样你就不会使用新的dequeueReusableCellWithIdentifier:forIndexPath:需要。

如果您使用自定义单元类,则使用新方法以及相应的注册方法(在viewDidLoad中),但如果要使用其中一个UITableViewCellStyle枚举,则使用旧方法。

+1

Upvoted指出,你不*必须*使用花哨的新方法。只有当它们适合你的目的或者如果替代品被弃用。 – SpacyRicochet

+0

如果你特别热衷,可以重写'dequeueReusableCellWithIdentifier:forIndexPath:'以提供一些以旧方式构建单元的标识符(并返回它们)。其他标识符将调用超级并返回。为这种类型的标识符创建一个标识符的NSDictionary到构造块可能是有意义的。 – Benjohn

11

可以使用故事板界面生成器避免外来亚类:

  1. 在故事板视图中,选择表视图细胞原型细胞(在表视图)
  2. 在公用事业视图中,在属性检查员,修改样式值
  3. (任选地)修改其他值,诸如选择与附件

新的IOS 6.0 dequeueReusableCellWithIdentifier:forIndexPath:在分配新单元格并返回时使用这些值。 (使用Xcode 4.5.2进行iOS 6.0编译测试)

6

保存一个文件的另一种方法是创建一个Nib并使用registerNib:forCellReuseIdentifier:代替。

制作笔尖很简单:在Interface Builder中创建一个新的.xib文件。删除默认视图。添加一个Table View Cell对象。使用属性检查器,更改单元格的样式。 (在这里,你也有机会通过调整其他属性进一步自定义单元格。)

然后在您的表视图控制器的viewDidLoad方法调用是这样的:

[self.tableView registerNib:[UINib nibWithNibName:@"StyleSubtitleTableCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"Cell"]; 
+0

initWithStyle:不调用reuseIdentifier。 – thierryb

-5

我对这个解决方法是调用initWithStyle: reuseIdentifier:后我已经使用[self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath]获得了它。毕竟,init只是另一个选择器,编译器不会在已经初始化的对象上调用它。然而,它会抱怨没有使用初始化调用的结果,所以我做的:

UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath]; 
cell = [cell initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellId"]; 

我想这不会在雨燕工作...

+0

这在Swift中正常工作。 – faraquet99

+0

最优雅的解决方案。希望initWithStyle的胆量不会再重新创建。 –

+2

好吧,我猜如果你这样做,你可以放弃离队的东西... – stk

0

Bolot的答案是正确的。简单,你不需要创建任何XIB文件。

我只是想更新他对任何人使用,而不是斯威夫特的Objective-C的做这件事的答案:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
    super.init(style: .value1, reuseIdentifier: reuseIdentifier) 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 
相关问题