Setting UITableViewCell style when using iOS 6 UITableView dequeueReusableCellWithIdentifier: forIndexPath:

I am trying to determine how to set UITableViewCellStyle when using new methods in iOS 6 for UITableView .

Previously, when creating a UITableViewCell I would change the enumeration of the UITableViewCellStyle to create different types of cells by default when calling initWithStyle: but from what I can collect, this is no longer the case.

Apple's documentation for a UITableView states:

Return value : A UITableViewCell object with an associated reuse identifier. This method always returns a valid cell.

Discussion : For performance reasons, a table view data source should usually reuse UITableViewCell objects when it assigns cells to rows in its tableView: cellForRowAtIndexPath: method. The table view maintains a queue or list of UITableViewCell objects that the data source is marked for reuse. Call this method from the data source object when it is asked to provide a new cell to represent the table. This method deactivates an existing cell, if available, or creates a new one based on a previously saved class or nib file.

It is important . You must register a class or nib file using the registerNib: forCellReuseIdentifier: or registerClass: forCellReuseIdentifier: method before calling this method.

If you register a class for the specified identifier and create a new cell, this method initializes the cell by calling its initWithStyle: reuseIdentifier: method. For nib-based cells, this method loads the cell object from the provided nib file. If an existing cell was reusable, this method instead calls the prepareForReuse method.

Here's what my new cellForRowAtIndexPath looks like after implementing new methods:

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

The code that I still work fine, but always returns the default style. How can I change this so that I can create cells with other styles like UITableViewCellStyleDefault , UITableViewCellStyleValue1 , UITableViewCellStyleValue2 and UITableViewCellStyleSubtitle ?

I don’t want to subclass UITableViewCell , I just want to change the default type, as I could do before iOS 6. It seems strange that Apple will provide advanced methods, but with minimal documentation to support their implementation.

Has anyone dealt with this or have encountered a similar problem? I try my best to find any reasonable information.

+80
uitableview ios6
Nov 01 '12 at 10:18
source share
6 answers

I know that you said you did not want to subclass, but it seems inevitable. Based on the build code, during testing in the iOS 6.0 simulator, UITableView creates new instances of UITableViewCell (or its subclasses) by executing

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

In other words, the style posted ( UITableViewCellStyleDefault ) looks tough. To get around this, you need to create a subclass that overrides the default initializer initWithStyle:reuseIdentifier: and conveys the style you want to use:

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

Also, it would be better to send registerClass:forCellReuseIdentifier: to viewDidLoad instead of doing this every time a cell is requested:

 - (void)viewDidLoad { [super viewDidLoad]; [self.tableView registerClass:<RegisteredClass> forCellReuseIdentifier:<ReuseIdentifier>]; } 
+101
Nov 02 '12 at 11:27
source share

dequeueReusableCellWithIdentifier not deprecated, so you do not need to use the new dequeueReusableCellWithIdentifier:forIndexPath:

Use the new method along with the corresponding register method (in viewDidLoad) if you use your own class of cells, but use the old method if you want to use one of the UITableViewCellStyle enumerations.

+59
Nov 22 '12 at 17:21
source share

You can avoid an extraneous subclass using the storyboard interface builder:

  • In the Storyboard view, select the prototype cell of the table cell (in the table view).
  • In the Utilities view in the attribute inspector, change the style value
  • (optional) Change other values, such as Selection and Accessory

The new iOS 6.0 dequeueReusableCellWithIdentifier:forIndexPath: uses these values ​​when distributing new cells and returning them. (Tested on compiling iOS 6.0 using Xcode 4.5.2)

+11
Feb 11 '13 at 2:16
source share

Another alternative that saves one file is to create a Nib and use registerNib:forCellReuseIdentifier: .

Creating Nib is very simple: create a new .xib file in Interface Builder. Delete the default view. Add a Cell View Table object. Use the Attributes Inspector to change the style for the cell. (Here you also have the option to configure the camera further by setting other attributes.)

Then in your view of the table controller viewDidLoad call something like:

 [self.tableView registerNib:[UINib nibWithNibName:@"StyleSubtitleTableCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"Cell"]; 
+6
Apr 18 '13 at
source share

The swamp answer is correct. Simple and you do not need to create a XIB file.

I just wanted to update his answer for those who do this using Swift instead of 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") } 
0
Dec 15 '17 at 14:40
source share

My solution is to call initWithStyle: reuseIdentifier: after I got it using [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath] . In the end, init is another selector, and the compiler does not make any restrictions on calling it on an already initialized object. However, he will complain that he will not use the result of calling init, so I:

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

I assume this will not work in Swift ...

-5
Jun 11 '15 at 8:17
source share



All Articles