I have created a customCell with UIButton and UILabel
code here:
ItemViewController.h:
#interface ItemViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
{
NSArray *arr;
IBOutlet ItemCustomCell *itemCell;
}
#property(nonatomic,retain)IBOutlet UITableView *tblItem;
ItemViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
ItemCustomCell *cell = (ItemCustomCell *) [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"ItemCustomCell" owner:self options:nil];
cell = itemCell;
}
cell.btnPlus.tag=indexPath.row;
[cell.btnPlus addTarget:self action:#selector(incrementValue:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
-(void)incrementValue:(UIButton *)btnAdd
{
NSLog(#"btn%d",btnAdd.tag);
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:btnAdd.tag inSection:0];
ItemCustomCell *cell = (ItemCustomCell*)[tblItem cellForRowAtIndexPath:indexPath];
cell.lblCount.text=[NSString stringWithFormat:#"%d",[cell.lblCount.text intValue]+1];
}
ItemCustomCell.h
#interface ItemCustomCell : UITableViewCell
{
}
#property(nonatomic,strong)IBOutlet UIButton *btnPlus;
#property(nonatomic,assign)IBOutlet UILabel *lblCount;
Default value of label is 1. When I click on the button it displays next value.
When I scroll up or down the tableView label value reset to 1. What I am doing wrong here?
For customCell, you need to specify its reuse identifier and its class name in Xib and load to your cell for reuse:
cell = [[[NSBundle mainBundle] loadNibNamed:#"ItemCustomCell" owner:self options:nil] lastObject];
EDIT
It's better to use IBOutlet and delegate to implement action inside CustomCell then use tag.
//ItemCustomCell.h
#class ItemCustomCell;
#protolcol ItemCustomCellDelegate
-(void) clickPlusButtonInsideCell:(ItemCustomCell *)cell;
#end
#interface ItemCustomCell
#property(weak, nonatomic) id<ItemCustomCellDelegate> delegate;
//Hookup with your view in Xib
#property (weak, nonatomic) IBOutlet UILabel *label;
-(IBACtion)clickPlusBut:(id)sender;
#end
//ItemCustomCell.m
-(IBACtion)clickPlusBut:(id)sender{
[self.delegate clickPlusButtonInsideCell:self];
}
Use
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
ItemCustomCell *cell = (ItemCustomCell *) [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"ItemCustomCell" owner:self options:nil] lastObject];
}
cell.delegate = self;
return cell;
}
-(void) clickPlusButtonInsideCell:(ItemCustomCell *)cell{
cell.label.text = #"something";
}
The problem is that you are setting the value of your label from a function associated to your button.
When you scroll your view, making your cell disappearing and re-appearing, your controller rebuild your cell.
So if you don't save the value of your label, you will lose it everytime your cell go out of the screen.
Add something (like an array) to save the value for each of your label. increase the value saved in the same time you are incrementing the value displayed.
You need to store the data seperately, in an array of integers for example. And when you show the cell get the value from the array.
Right now your value is stored in the label, but when you refresh you lose that data and it resets to the default value of 1.
So in your cellForTableRow you set the label text to the value from the array. And in your second method you increase the value stored in the array and then reload data (or change the label manually like you do now.)
You should follow the following approach while using UITableViewCell from nib.
if (cell == nil) {
NSArray *topLevelArray = [[NSBundle mainBundle] loadNibNamed:#"ItemCustomCell" owner:self options:nil];
cell = [topLevelArray objectAtIndex:0];
}
You already have answers about storing the state of the cell outside the cell, because it gets reset when it is recycled. Those are correct.
If the selected state is important - then store it in the object that the cell is representing. That way, if you are configuring the cell based on this object, it will correctly persist through recycling.
If the state is transient, and doesn't need to be stored in the object, you need to store this state somewhere. There are a couple of answers about using an NSArray to store this state. I personally prefer to use an NSDictionary with the indexPath as the key. Since NSIndexPath conforms to NSCopying it can be used as the key for an NSDictionary.
Found a solution, in numberOfSectionInTableView i have to apply a condition based on the state of the tableview and change the label value accordingly. i was using paging so that is the solution.
if someone else is not using paging in a tableview then just set a value before sending a JSON request and apply condition based on the value in numberOfSectionInTableView and it will work.
Your code is displaying next value because your are incrementing value on button click.
cell.lblCount.text=[NSString stringWithFormat:#"%d", [cell.lblCount.text intValue]+1];
And tableView label value are resetting to 1 because new cell creates each time.
You should need to know more about tableview how it work and how to use reusable cell. Have a look this article A Closer Look at Table View Cells
Related
I have a UITableView which has another UITableView nested inside one its cells (I know this is bad practise, don't worry!).
The problem is that when I call dequeueReusableCellWithIdentifier: I am getting nil back. HOWEVER this works just fine when the UITableView is not nested inside another one.
Is there a way to NOT reuse a UITableViewCell, but instead directly instatiate it every time?
I've tried using this:
ContactFieldCell *cell = [[ContactFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:thisCellIdentifier];
which doesn't return nil, but then nothing appears in my UITableView!
Here's the code for the "parent" UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ContactCardCell";
ContactCardCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *objects = [[sections objectAtIndex:indexPath.section] objectForKey:#"objects"];
CDCard *card = [objects objectAtIndex:indexPath.row];
cell.delegate = self;
cell.fieldsTableView = [[CardTableViewController alloc] initWithCard:card];
[cell.fieldsTableView.view setFrame:CGRectMake(17, 12, 256, 163)];
[cell.contentView addSubview:cell.fieldsTableView.view];
return cell;
}
and here's the code for the "child" UITableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *thisCellIdentifier = #"ContactFieldCell";
ContactFieldCell *cell = [self.tableView dequeueReusableCellWithIdentifier:thisCellIdentifier];
cell.delegate = self;
cell.field = [self.card.sortedFields objectAtIndex:indexPath.row];
return cell;
}
ContactFieldCell is a prototype cell within the storyboard. It has the following code:
#interface ContactFieldCell : UITableViewCell
#property (nonatomic, weak) id<ContactFieldCellDelegate> delegate;
#property (nonatomic, strong) CDField *field;
#property (nonatomic, strong) IBOutlet UILabel *displayNameLabel;
#end
dequeueReusableCellWithIdentifier: does not create a cell if none was found for dequeueing.
Create a cell manually, or use dequeueReusableCellWithIdentifier:forIndexPath:
Yes - #vikingosegundo is correct, but to expand his answer, you need to also register your cell first. dequeueReusableCellWithIdentifier: may return nil. And if it is you need to create your cell,s but dequeueReusableCellWithIdentifier: forIndexPath: will always return a valid cell, the catch is you need to tell it what kind of cell, that is what registerClass does.
Do this for both UITableViews.
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[ContactFieldCell class] forCellReuseIdentifier:#"ContactFieldCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *thisCellIdentifier = #"ContactFieldCell";
ContactFieldCell *cell = [self.tableView dequeueReusableCellWithIdentifier:thisCellIdentifier forIndexPath:indexPath];
cell.delegate = self;
cell.field = [self.card.sortedFields objectAtIndex:indexPath.row];
return cell;
}
UITableViews are a very powerful element and can be used to build great apps.
The only thing to keep in mind is, the basics must be clear. Now from your code, I cannot make out whether you have assigned the delegates and dataSources properly, but I'll still mention it in case someone else needs it.
You have a subclassed UITableViewCell which in turn contains a UITableView. The UIViewController must be the delegate and dataSource for the outer UITableView. Make sure you have set it in both the .h and .m file.
Next, your custom cell must also be the delegate and dataSource, but for the inner UITablewView. I suppose here, you have created the inner UITableView in the init method of the UITableViewCell. Set the delegate and dataSource there itself. Then you set other runtime properties in the drawRect method (if needed) and call it's reloadData.
The UIViewController must override the delegate and dataSource methods for the outer table and the cell must override the methods for the inner table.
Also, make sure, the time the cells are plotted, your data is not nil or null.
And a very important fact, that people miss is the following code:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
Just dequeueing the cell is not enough. The first time a cell is dequeued, it is nil because it has not been created yet. Hence the if condition. Once it is allocated and initialized and added to the table, the dequeue code works thereafter.
NOTE : After looking more closely to your code (sorry for not looking the first time), I noticed you have allocated a UITableViewController to your cell. How do you think the cell is going to display a controller? Use a UITableView instead. Try to follow the pattern I have mentioned in paragraph 3. Use a table in the custom cell as a private member (or property, your wish), allocate it in init. Assign the data to the cell from your view controller. Then use this data to set the inner table view cell's properties in it's drawRect. It should work fine.
I have a problem with my cell textfield values when scrolling on a UITableView. When I scroll down and hide a custom cell, the value of the textField is deleted. The dequeueReusableCellWithIdentifier method doesn't work. I have this:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SectionsTableIdentifier = #"MyCustomCell";
MyCustomCell *cell = (MyCustomCell *) [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if (cell == nil) {
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:#"MyCustomCell" owner:self options:nil];
cell = [objects objectAtIndex:0];
}
cell.labelCustomAttribute.text= #"Attribute Name";
cell.textFieldCustomAttribute.delegate = self;
return cell;
}
I find it easier to register the custom cell with the tableView in the viewDidLoad method and then simply use dequeueReusableCellWithIdentifier. If you register the cell, the dequeue method will automatically pick up a reusable cell OR allocate a new custom cell (if none is available).
Example:
-(void)viewDidLoad
{
[super viewDidLoad];
// Get a point to the customized table view cell for MyCustomCell
UINib *myCustomCellNib = [UINib nibWithNibName:#"MyCustomCell" bundle:nil];
// Register the MyCustomCell with tableview
[[self tableView] registerNib:myCustomCellNib forCellReuseIdentifier:#"MyCustomCell"];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SectionsTableIdentifier = #"MyCustomCell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
cell.labelCustomAttribute.text= #"Attribute Name";
cell.textFieldCustomAttribute.delegate = self;
return cell;
}
Normally the reuseIdentifier is assigned in the UITableViewCell's initWithStyle:reuseIdentifier: method, which you are not using because you are loading your view from a Nib.
You cannot set this property after because it is read only.
Maybe you can try instanciating the cell using the standard initWithStyle:reuseIdentifier: and add the view from your Nib as a subview of the cell's ContentView...
Now what is happening in your case is that you create a new cell every time that the Table View needs to display one. Clearly, this is not going to work. Actually, if you were reusing cells, you would have to also store the content of your text field somewhere (preferably in your data source) and put it when you reuse the cell. If you do not store it, when the cell is going to be reused, it will contain the data from the previous row in which it was displayed.
I am trying to create a "settings" table view for my app. I am trying to mimic it to be the same style as the gneral setting on an Iphone. I have created my own custom cell class by inheriting from UITableCell. I gave it the appropriate IBOulets and i have hooked them up in the storyboard. I also hooked up the switch to my tableViewControler, but for some reason my code is only returning me one empty cell (it being only one cell is not an issue atm for that's all i have in my setting). I triple checked and made sure that I'm using the same cell identifier in my code and in storyboard. Anyone know why I'm getting a blank cell back?
Here is my .h file for my custom cell.
#interface NHPSettingsCell : UITableViewCell
#property (nonatomic,weak) IBOutlet UILabel *settingLabel;
#property (nonatomic,strong) IBOutlet UISwitch *settingSwitch;
#end
MY Problem code is here, my .h file for the custom cell:
#import "NHPSettingsCell.h"
#implementation NHPSettingsCell
#synthesize settingLabel, settingSwitch;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
My method for drawing the cell in my custom view controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SettingsCell";
NHPSettingsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[NHPSettingsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellStyleDefault;
}
cell.settingLabel.text = #"firstSetting";
//check the if user wants promt of disclaimer each time or not.
if([prefs boolForKey:#"firstSetting"] == YES){
cell.settingSwitch.on = YES;
}else{
cell.settingSwitch.on = NO;
}
return cell;
}
Now the thing that annoys me is i have successfully managed to implement the cellForRowAtIndexPath method for a dynamic table that uses custom cells. I have also implements the code for a static table using the default cell, but for a static table with custom cells it just doesn't seem to work. Here is the code on how I implemented my custom cells on a dynamic table (note how i didn't have to init the cells but it works).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"InteractionResultCell";
NHPResultCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure & Fill the cell
cell.leftLabel.text = [[resultsList objectAtIndex:indexPath.row] substanceName];
cell.rightLabel.text = [[resultsList objectAtIndex:indexPath.row] substanceName2];
NSString *color = [NSString stringWithFormat:#"%#", [[resultsList objectAtIndex:indexPath.row] color]];
//Change a hex value to a readable 0x number to pass ot hte macro so we can go from a hex color to a RGB system.
NSScanner *scanner;
unsigned int tempint=0;
scanner = [NSScanner scannerWithString:color];
[scanner scanHexInt:&tempint];
cell.severityButton.backgroundColor = UIColorFromRGB(tempint);
return cell;
}
Two problems:
If you are using static cells, do not implement any datasource methods in your view controller (numberOfRows, numberOfSections, cellForRow...) as this will override what you have built in the storyboard. The table has the sections, rows and content you give it in the storyboard.
Cells loaded from the storyboard (either dynamic prototypes, or static cells) are initialised using initWithCoder:, not initWithStyle:. awakeFromNib: is a better place to put your set up code.
dequeueReusableCellWithIdentifier: works only if a cell has already been created to prevent repeated memory allocations. You cannot reuse a cell without creating it first. The static cells created in the xib are the default type. That's why it doesn't work for static table with custom cells. Add the cell creation code after reuse as you've done in your custom view controller's cellForRowAtIndexPath: method:
if (cell == nil) {
cell = [[NHPSettingsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellStyleDefault;
}
EDIT- To init your custom cell, you'll have to load from xib. Add the following class method to your NHPSettingsCell.m:
+(NHPSettingsCell*) createTextRowWithOwner:(NSObject*)owner{
NSArray* wired = [[NSBundle mainBundle] loadNibNamed:#"NHPSettingsCell" owner:owner options:nil];
NHPSettingsCell* cell = (NHPSettingsCell*)[wired firstObjectWithClass:[NHPSettingsCell class]];
return cell;
}
and then call it from your custom view controller as:
cell = (NHPSettingsCell*)[tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (Nil == cell) {
cell = [NHPSettingsCell createTextRowWithOwner:self];
}
I'd like to create custom UITableViewCell using an XIB, but I'm not sure how to recycle it using UITableViewController's queueing mechanism. How can I accomplish this?
Folks, this question was intended to be self answered as per the FAQ, although I love the awesome responses. Have some upvotes, treat yourself to a beer. I asked this because a friend asked me and I wanted to put it up on StackOverflow. If you have anything to contribute, by all means!
If you're using iOS 5 you can use
[self.tableView registerNib:[UINib nibWithNibName:#"nibname"
bundle:nil]
forCellReuseIdentifier:#"cellIdentifier"];
Then whenever you call:
cell = [tableView dequeueReusableCellWithIdentifier:#"cellIdentifier"];
the tableview will either load the nib and give you a cell, or dequeue a cell for you!
The nib need only be a nib with a single tableviewcell defined inside of it!
Create an empty nib and add the table cell as the first item. In the inspector, you can add the reuseIdentifier string in Interface Builder.
To use the cell in your code, do this:
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *reuseIdentifier = #"blah"; //should match what you've set in Interface Builder
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell == nil)
{
cell = [[[NSBundle mainBundle] loadNibNamed:#"YourTableCellNib" owner:nil options:nil] objectAtIndex:0];
}
//set up cell
return cell;
}
There is another method where you create an outlet for your cell and load the cell nib using the controller as the file's owner, but honestly this is much easier.
If you want to be able to access the subviews you've added to the cell in the nib, give them unique tags and access them with [cell viewWithTag:x];
If you want to be able to set custom properties on the cell, you'll need to create a custom UITableViewCell subclass, then just set that as the class of your nib in InterfaceBuilder and cast the UITableViewCell to your custom subclass when you dequeue it in the code above.
To set up a custom UITableViewCell using a XIB, you have to do several things:
Set up an IBOutlet in your header
Configure the table view cell in Interface Builder
Load the XIB inside of tableView:cellForRowAtIndexPath:
Configure it like any other cell
So... Let's set up an IBOutlet in the header file.
#property (nonatomic, retain) IBOutlet UITableViewCell *dvarTorahCell;
Don't forget to synthesize it inside the implementation file.
#synthesize dvarTorahCell;
Now, let's create and configure the cell. You want to pay attention to the Cell Identifier and the IBOutlet as shown below:
Now in code, you load up the XIB into your cell as shown here:
Notice that the Cell Identifier in Interface Builder matches the one shown in the code below.
Then you go ahead and configure your cell like any other.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"YUOnlineCell" owner:self options:nil];
cell = dvarTorahCell;
dvarTorahCell = nil;
}
//configure your cell here.
Just note that when accessing subviews, such as labels, you now need to refer to them by tag, instead of by property names, such as textLabel and detailTextLabel.
Here how you can do:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
YourCustomeCell *cell = (YourCustomeCell *)[tableView dequeueReusableCellWithIdentifier:CellClassName];
if (!cell)
{
NSArray *topLevelItems = [cellLoader instantiateWithOwner:self options:nil];
cell = [topLevelItems objectAtIndex:0];
}
return cell;
}
Where cellLoader in .h is defined as follow:
UINib *cellLoader;
and in .m is istantiated as follows (for example during initialization):
cellLoader = [[UINib nibWithNibName:CellClassName bundle:[NSBundle mainBundle]] retain];
and CellClassName is the defined in .m as follows (is also the name for your xib).
static NSString *CellClassName = #"YourCustomeCell";
Do not forget to use the string CellClassName also in your xib created cell.
For further info I suggest you to read this fantastic tutorial creating-a-custom-uitableviewcell-in-ios-4.
Hope it helps.
P.S. I suggest you to use UINib because is an optimized method to load xib files.
i have a uitableview in the uiviewcontroller, i made a scrollview in the viewload event.
i am adding it to tableview's first cell. but i scroll the tableview it displays more than one scrollview after 5 cell passed.
here is the code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"customCell";
DetailCellViewController *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nibObjects =[[NSBundle mainBundle] loadNibNamed:#"DetailCellView" owner:nil options:nil];
for (id currentObject in nibObjects)
{
if ([currentObject isKindOfClass:[DetailCellViewController class]])
{
cell = (DetailCellViewController *) currentObject;
}
}
}
if (indexPath.row==0) {
[cell.contentView addSubview:scrollView];
}
else {
NSMutableDictionary *dictionary=[catData objectAtIndex:indexPath.row-1];
NSString *title =[dictionary objectForKey:#"title"]];
[cell.catTitle setText:title];
}
return cell;
}
in which event should i add & remove scrollview?
My guess is that you're getting a dequeued UITableViewCell that already contains the UIScrollView. If you really care about separating cell types, I'd recommend setting it up so that you at least have two CellIdentifier strings. (There are times where I've set up a UITableView to handle 4+ different cell types; once you go beyond one cell type, it's pretty much just more of the same.)
My suggested solution: (see explanation below code)
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"bodyCell";
static NSString *HeaderIdentifier = #"headerCell";
UITableViewCell *cell;
// I break this up into 3 sections
// #1. Try to dequeue a cell
// #2. Create a new cell (if needed)
// #3. Set up the cell I've created
// Step 1: Try to dequeue a cell
if ([indexPath section] == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:HeaderIdentifier];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
// At this point, we may or may not have a cell to use,
// so we check for the cell's value being equal to 'nil'
// and create a new cell if it is
// Step 2: Create a new cell (if needed)
if (cell == nil) {
// Again, here we check for section to determine
// what kind of cell we want
if ([indexPath section] == 0) {
// We have the "header"/first cell
// Option 1
cell = [[ScrollViewTableViewCell alloc] init];
// Option 2 (this assumes you've got a xib named
// ScrollingTableViewCell along with a class property
// named headerCell and have properly wired it up in
// Interface Builder)
[[NSBundle mainBundle] loadNibNamed:#"ScrollingTableViewCell"
owner:self
options:nil];
cell = [self headerCell];
[self setHeaderCell:nil];
} else {
// We have a "body" cell (anything other than the first cell)
// Option 1
cell = [[BodyTableViewCell alloc] init];
// Option 2 (again, assuming you've set things up properly)
[[NSBundle mainBundle] loadNibNamed:#"BodyTableViewCell"
owner:self
options:nil];
cell = [self bodyCell];
[self setBodyCell:nil];
}
}
// At this point, whether dequeued or created
// new, 'cell' should be populated
// Again, we check for section and set up the cell as appropriate
if ([indexPath section] == 0) {
// Set up the header (UIScrollView) cell as appropriate
// This is where you would add the UISCrollView to your cell
// (if you haven't set up the UIScrollView through Interface Builder)
} else {
// Set up the "body" cell as appropriate
}
return cell;
}
NOTE: I HIGHLY recommend using Option 2 above. By far, the best results I've found when using custom/non-standard UITableViewCells is to make my own UITableViewCell subclass and xib to go along with it. Here are the steps for that:
Create a subclass of UITableViewCell (we'll call yours ScrollingTableViewCell.h/.m)
Class forward/import ScrollingTableViewCell into your UITableViewController (or UIViewController that's hosting a UITableView).
Create a class property of type ScrollingTableViewCell (we'll call yours ScrollingCell).
Create a View (New File > User Interface > View) (we'll call yours ScrollingTableViewCell.xib).
Delete the stock view item in the xib and replace it with a UITableViewCell item.
Alternative #4/5
Create an empty Xib.
Add a UITableViewCell item.
VERY IMPORTANT
In the xib, the File's Owner is the ViewController, NOT the UITableViewCell. The cell's class is ScrollingTableViewCell.
In IB, connect the ViewController's ScrollingCell property to the UITableViewCell item.
If you follow the above instructions, you should be able to allocate your cell using Option 2 above and then you can set up your cell in ScrollingTableViewCell.h/.m.