I have UITableViewCell with detailed arrow that points to top or to down.
Than I tap on this cell I want to expand it. So I will reload UITableView and I want to animate rotation ofUIImageView`.
Question - is it possible to animate rotation of UIImageView simultaneously with reloading data in UITableView?
Yes, you can create a table with expandable/contactable cell's, also while expanding you can animate the containers of the cell's.
But, one thing until and unless it is a requirement to reload table, I'll suggest you to reload row with the animations performed simultaneously.
Also as you asked in comment what's the best way to track whether the cell needs to be shown simple or detailed, I think it depends on your requirements, like if you need to show only one cell expanded at a time, then you just keep the index of current expanded cell in the class else if you need to show more than one cell expanded at a time than you can use the data source to keep the information whether the cell needs to be show as simple or detailed. If you do not have the data source then you can do the same by creating a list of cell's index path keeping track of detailed cells.
Programmatically you need to do following things to show simple/ detailed cells-
Note: I have assumed to show only one cell expanded at a time.
1) Create a member variable to keep track of expanded cell.
NSIndexPath *expandedCellIndexPath;
2) Return height for expanded cell(if expanded) otherwise for simple cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([expandedCellIndexPath compare:indexPath] == NSOrderedSame)
return 100.0f;
return 50.0f;
}
3) Create cell as-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cellId";
CustomCell *customCell = nil;
customCell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(customCell == nil)
{
NSString *nibName = #"CustomCell_iPhone";
customCell = (CustomCell *)[[[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil] lastObject];
customCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
if([expandedCellIndexPath compare:indexPath] == NSOrderedSame)
{
[customCell.m_arrowImageView setImage:[UIImage imageNamed:DOWN_ARROW_KEY]];
[self showSelectedCellAnimations:customCell];
}
else
{
[customCell.m_arrowImageView setImage:[UIImage imageNamed:UP_ARROW_KEY]];
[self showUnSelectedCellAnimations:customCell];
}
// you can also set default up arrow image and rotate it with down arrow image and vice versa
return customCell;
}
4) Rotate Up/Down arrow image using-
- (void)rotateImage:(UIImageView *)image duration:(NSTimeInterval)duration
curve:(int)curve degrees:(CGFloat)degrees
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:YES];
CGAffineTransform transform =
CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees));
image.transform = transform;
[UIView commitAnimations];
}
5) Call above method as-
[self rotateImage:customCell.m_helpImage duration:0.25
curve:UIViewAnimationCurveEaseIn degrees:0.0];
6) Inside didSelectRowAtIndexPath: set the expandedCellIndexPath to the current index path which needs to be expanded and reload previous expanded row to contract and reload current expandedCellIndexPath row to expand, like-
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
CustomCell *customCell = nil;
customCell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath];
NSIndexPath *previousIndexPath = expandedCellIndexPath;
if([expandedCellIndexPath compare:indexPath] != NSOrderedSame)
expandedCellIndexPath = indexPath;
[self.m_tableView reloadRowsAtIndexPaths:#[previousIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.m_tableView reloadRowsAtIndexPaths:#[expandedCellIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.m_tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
Related
I am trying to perform an animation on a cell when the accessory view is tapped. The tapped delegate method is firing and I can get the row to do something--change label, but it is ignoring the animation (or in another case--not even making the change.) How can I get the animation to work properly?
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
MyCustomCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[UIView animateWithDuration:5.0
delay: 5.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
//NEXT TWO LINES HAVE NO EFFECT ON CELL SO COMMENTED OUT
//cell.nameLabel.text = #"Thank you. FIRST ANIMATE TRY";
// [self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
//NEXT THREE LINES CHANGE TEXT BUT WITHOUT ANIMATION
[self.tableView beginUpdates];
cell.nameLabel.text = #"Thank you. Second try!";
[self.tableView endUpdates];
}
completion:^(BOOL finished){
NSLog(#"animation finished");
}];
}
BTW I also tried explicitly dispatching this in the main queue but it had no effect. It should already be in main queue.
First of all, you don't need to call beginUpdates or endUpdates. Second, you can't animate the change of a label's text value.
What you need to is have a label on the cell and initialize the alpha property to 0.0. When accessoryButtonTappedForRowWithIndexPath is called set the alpha property to 1.0 inside of your animation block.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AwesomeCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.thankYouLabel.text = #"Thank you";
cell.thankYouLabel.alpha = 0.0;
return cell;
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
AwesomeCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[UIView animateWithDuration:1.0 animations:^{
cell.thankYouLabel.alpha = 1.0;
}];
}
I have a tableview which can be expanded on selecting the cell and collapses on selecting again. When you select, the cell should expand and display a label and when you select again it collapses and hides the label . The expanding and collapsing works fine, but if i scroll the tableview after expanding a cell it behaves weird. Once it goes out of the view and comes back , the cell will have the expanded cell's height but the label which is supposed to be shown in expanded cell is hidden.If i select the cell again it collapses and displays the label. I use ,
- (CGFloat)tableView:(UITableView *)t heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:t cellForRowAtIndexPath:indexPath];
if([self cellIsSelected:indexPath])
return cell.frame.size.height+35;
return cell.frame.size.height;
}
- (BOOL)cellIsSelected:(NSIndexPath *)indexPath {
// Return whether the cell at the specified index path is selected or not
NSNumber *selectedIndex = [self.selectedIndexes objectForKey:indexPath];
return selectedIndex == nil ? FALSE : [selectedIndex boolValue];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Deselect cell
NSLog(#"Select cell:%#",indexPath);
[self.tableView deselectRowAtIndexPath:indexPath animated:TRUE];
if([self pickTaskForIndexPath:indexPath].productSpecialMessage){
BOOL isSelected = ![self cellIsSelected:indexPath];
NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
[self.selectedIndexes setObject:selectedIndex forKey:indexPath];
PickTaskTableviewCell *cell= [self.tableView cellForRowAtIndexPath:indexPath];
cell.message.hidden=false;
cell.messageLabel.text=[self pickTaskForIndexPath:indexPath].productSpecialMessage;
cell.messageLabel.lineBreakMode=NSLineBreakByTruncatingTail;
cell.messageLabel.numberOfLines=3;
if(cell.messageLabel.hidden==true){
cell.messageLabel.hidden = false;
} else {
cell.messageLabel.hidden = true;
}
NSLog(#"message:%#",cell.messageLabel.text);
[cell layoutIfNeeded];
}
self.tableView.rowHeight=UITableViewAutomaticDimension;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
indexPath is added to the selectedIndexes on didSelectRowAtIndexPath
Please help me
Cells should be configured only within cellForRowAtIndexPath. When a state change occurs that makes a cell need to look different, just reload that cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PickTaskTableviewCell *cell = (PickTaskTableviewCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
// everything else you do to configure the cell goes here, then ...
// check the logic here, we want one condition that tells us whether to show the labels
if([[self cellIsSelected:indexPath] && self pickTaskForIndexPath:indexPath].productSpecialMessage){
// don't need these here
//NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
// [self.selectedIndexes setObject:selectedIndex forKey:indexPath];
// PickTaskTableviewCell *cell= [self.tableView cellForRowAtIndexPath:indexPath];
cell.message.hidden=false;
cell.messageLabel.text=[self pickTaskForIndexPath:indexPath].productSpecialMessage;
cell.messageLabel.lineBreakMode=NSLineBreakByTruncatingTail;
cell.messageLabel.numberOfLines=3;
cell.messageLabel.hidden=NO;
} else {
cell.message.hidden=YES;
cell.messageLabel.hidden=YES;
}
NSLog(#"message:%#",cell.messageLabel.text);
// don't need this here
// [cell layoutIfNeeded];
return cell;
}
Selection (and presumably deselection) cause the need to update the cell, so...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// don't deselect it here, just reload it
// more on this later...
[self.selectedIndexes setObject:selectedIndex forKey:indexPath];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
// probably do the same in didDeselectRowAtIndexPath:
One last (optional) point. There's no need to maintain your own list of selected index paths, UITableView does that for you, so you could delete your selectedIndexes property and just use the table view methods, e.g....
- (BOOL)cellIsSelected:(NSIndexPath *)indexPath {
// Return whether the cell at the specified index path is selected or not
return [[self.tableView indexPathsForSelectedRows] containsObject:indexPath];
}
I'm attempting to implement an inline UIPicker inside a table-view cell, similar to both this and this SO question. I believe I'm close in my implementation, but at the moment, no picker is displayed when I select the appropriate cell. Can anyone point me in the right direction in regards to what I'm doing wrong? Thank you!
Below is where I determine what rows occur in each section:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {
case NotificationsSection:
return [self tableView:tableView cellForAreaOneRowAtIndexPath:indexPath];
break;
case RedZoneSection:
return [self tableView:tableView cellForAreaTwoRowAtIndexPath:indexPath];
break;
case TimeOfDaySection:
return [self tableView:tableView cellForAreaThreeRowAtIndexPath:indexPath];
break;
default:
return nil;
break;
}
}
Below is where I check the number of rows in each section. I suspect my problem may lie here, but I am not completely sure.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case AreaOneSection:
return AreaOneRows;
break;
case AreaTwoSection:
return TotalAreaTwoRows;
break;
case AreaThreeSection:
return TotalAreaThreeRows;
break;
default:
return 0;
break;
}
}
Below is where I return the height for each row:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat rowHeight = self.tableView.rowHeight;
// if (indexPath.section == TimeOfDaySection && indexPath.row == HourTimeZoneRow && self.timePickerIsShowing == NO){
return rowHeight;
}
Finally, below is where I check if the user selected the index path that I want to insert the UIPicker cell below. If they did, then I call a method to show the the picker.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.section == SectionThree && indexPath.row == RowOne && self.timePickerIsShowing == NO){
[tableView beginUpdates];
[self showTimePicker];
[tableView endUpdates];
} else{
[self hideTimePicker];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
Finally, below is where I show and hide the UIPicker.
- (void)showTimePicker
{
self.timePickerIsShowing = YES;
self.timePicker.hidden = NO;
//build the index path to where the picker should be inserted here
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:HourTimeZoneRow + 1 inSection:TimeOfDaySection];
static NSString *CellIdentifier = #"TimePickerCell";
UITableViewCell *cell = (UITableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
_timePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 160)];
[cell.contentView addSubview:self.timePicker];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView reloadData];
self.timePicker.alpha = 0.0f;
[UIView animateWithDuration:0.25 animations:^{
self.timePicker.alpha = 1.0f;
}];
}
- (void)hideTimePicker {
self.timePickerIsShowing = NO;
self.timePicker.hidden = YES;
[self.tableView reloadData];
[UIView animateWithDuration:0.25
animations:^{
self.timePicker.alpha = 0.0f;
}
completion:^(BOOL finished){
self.timePicker.hidden = YES;
}];
}
In your showPicker function, you don't seem to do anything? You create a cell, do things with it then it dies when that function ends. The cell is not added anywhere from what I can see?
You need to add the picker inside cellForRowAtIndexPath, for the index path you know needs a picker.
What I do requires very little coding. I create a prototype cell in interface builder which contains a picker view. In my case I also add a toolbar above the picker which I can put buttons in to allow Cancel and Done. Add suitable properties to pass in the current values for the picker to show initially. Add a delegate to use to inform the creator (your tableView) of changes in picker values. You can wait for it to finish picking, or use it to update live the cell its editing values for by reloading the cell being edited every time the value changes. I prefer that the picker can pick a value and you can commit it or cancel it.
When a cell needs edited, I update my data model to insert an editing entry then call [tableView reload]. In my case selecting a cell starts editing, clicking cancel/done ends editing.
The table view at this point will start asking for cells. This time one of those will be your new picker cell, which will be for editing the cell it is below. When you create it you pass it the data model reference for the data it is to edit.
So you can achieve all this by simply adding a new prototype cell type and creating it inside cellForRowAtIndexPath when required.
You have a choice as to how to remove the picker. In my case I have Cancel/Done buttons which just removes the entry from the data model and reloads the table again, resulting in it never being created. You could also make the mode as being click on a cell to add and click again to remove. Again you just update the data model and reload. See how the time picker works on the Calander app for a new appointment.
You may be thinking this is a lot of reloads. However it only affects what is on screen and I found it to be easier than trying to figure out the affected cells all the time. Its also very smooth. When it is working you can always optimize the code.
Use constraints in the cell to make sure it has the layout you want.
I have a table view of custom cells and some buttons in each cell.Clicking on any of the button inside the cell will reveal another custom view below that cell.Next click on the same button will collapse the view and need this same for all cells.I tried with insertrow method on the button click but in vain.How can i do this with using only the table view delegates.
This is what i tried:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"CustomCell_For_Dashboard";
CustomCellFor_Dashboard *customCell = (CustomCellFor_Dashboard *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (customCell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCellFor_Dashboard" owner:self options:nil];
customCell = [nib objectAtIndex:0];
}
[customCell.howyoulfeelBtn addTarget:self action:#selector(buttonclicked:) forControlEvents:UIControlEventTouchUpInside];
customCell.nameLabel.text = #"test";
customCell.imgView.image = [UIImage imageNamed:#"Default.png"];
// customCell.prepTimeLabel.text = [prepTime objectAtIndex:indexPath.row];
return customCell;
}
-(void)buttonclicked:(id)sender{
NSIndexPath *indexPath = [myTable indexPathForCell:sender];
[myTable beginUpdates];
NSIndexPath *insertPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
[myTable insertRowsAtIndexPaths:[NSArray arrayWithObject:insertPath] withRowAnimation:UITableViewRowAnimationTop];
}
can anyone help me?
I got the same task on one project with just one thing different: There were no buttons, just tapping on cell will expand or collapse it.
There are several things you should edit in your code. First, the button method code will look something like this:
- (void) collapseExpandButtonTap:(id) sender
{
UIButton* aButton = (UIButton*)sender; //It's actually a button
NSIndexPath* aPath = [self getIndexPathForCellWithButtonByMagic:aButton];
//expandedCells is a mutable set declared in your interface section or private class extensiont
if ([expandedCells containsObject:aPath])
{
[expandedCells removeObject:aPath];
}
else
{
[expandedCells addObject:aPath];
}
[myTableView beginEditing];
[myTableView endEditing]; //Yeah, that old trick to animate cell expand/collapse
}
Now the second thing is UITableViewDelegate method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([expandedCells containsObject:indexPath])
{
return kExpandedCellHeight; //It's not necessary a constant, though
}
else
{
return kNormalCellHeigh; //Again not necessary a constant
}
}
Key thing here is to determine if your cell should be expanded/collapsed and return right height in delegate method.
Going off of what #eagle.dan.1349 said, this is how to do it on the clicking of the cell. In storyboard, you also need to set the table cell to clip subviews, otherwise the content that would be hidden will show.
.h
#property (strong, nonatomic) NSMutableArray *expandedCells;
.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.expandedCells containsObject:indexPath])
{
[self.expandedCells removeObject:indexPath];
}
else
{
[self.expandedCells addObject:indexPath];
}
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat kExpandedCellHeight = 150;
CGFloat kNormalCellHeigh = 50;
if ([self.expandedCells containsObject:indexPath])
{
return kExpandedCellHeight; //It's not necessary a constant, though
}
else
{
return kNormalCellHeigh; //Again not necessary a constant
}
}
Saw this post and just wanted to give my 2 cents as my solution to this is very similar to the chosen answer (the tapping of a whole area).
Many people architect this by using just cells alone, but I believe there is a way to build this that might align better with what people are trying to achieve:
There are headers and there are cells. Headers should be tappable, and then cells underneath the headers would show or hide. This can be achieved by adding a gesture recognizer to the header, and when tapped, you just remove all of the cells underneath that header (the section), and viceversa (add cells). Of course, you have to maintain state of which headers are "open" and which headers are "closed."
This is nice for a couple of reasons:
The job of headers and cells are separated which makes code cleaner.
This method flows nicely with how table views are built (headers and cells) and, therefore, there isn't much magic - the code is simply removing or adding cells, and should be compatible with later versions of iOS.
I made a very simple library to achieve this. As long as your table view is set up with UITableView section headers and cells, all you have to do is subclass the tableview and the header.
Link: https://github.com/fuzz-productions/FZAccordionTableView
I also had a same situation and my solution was to put a button on top of the Section Title with viewForHeaderInSection method.
noOfRows defines how many rows are there in each section and button.tag keeps which button of section is pressed.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIButton *btnSection = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, tableView.frame.size.height)];
btnSection.tag = section;
[btnSection setTitle:[sectionArray objectAtIndex:section] forState:UIControlStateNormal];
[btnSection addTarget:self action:#selector(sectionButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
return btnSection;
}
- (void)sectionButtonTapped:(UIButton *)button {
sectionIndex = button.tag;
if (button.tag == 0) {
noOfRows = 3;
} else if (button.tag == 1) {
noOfRows = 1;
} else if (button.tag == 2) {
noOfRows = 2;
}
[self.tableView reloadData];
}
Hope this will help you..
I am having issues with my tableView not firing the didSelectRowAtIndexPath method. I have implemented the delegates as such:
#interface ViewController : UIViewController<UITableViewDataSource, UITableViewDelegate,UIScrollViewDelegate>
And in my storyboard the tableView's data source and delegate are both pointed at the base View Controller. I have User Interactions enabled as well as Selection set to Single Selection, and it is not the TapGesture problem since my tap gestures are not bound to the view and I have checked and they do not fire.
This is the code for setting up the table:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return menuArray.count;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"menuCell"];
NSDictionary *menuItem = [menuArray objectAtIndex:indexPath.row];
cell.textLabel.text = menuItem[#"Title"];
cell.detailTextLabel.text = menuItem[#"Subtitle"];
return cell;
}
-(void)showMenu{
[UIView animateWithDuration:.25 animations:^{
[content setFrame:CGRectMake(menuTable.frame.size.width, content.frame.origin.y, content.frame.size.width, content.frame.size.height)];
}];
}
-(void)hideMenu{
[UIView animateWithDuration:.25 animations:^{
[content setFrame:CGRectMake(0, content.frame.origin.y, content.frame.size.width, content.frame.size.height)];
}];
}
-(IBAction)showMenuDown:(id)sender {
if(content.frame.origin.x == 0)
[self showMenu];
else
[self hideMenu];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//whatever
}
The table is initially out of view on the storyboard (origin.x is set to -150), then when the user clicks on a button in the navigationBar, the view slides over to reveal it, which is what might be causing the problem I think.
Is there anything wrong with my code or implementation that would be causing this to not work?
If you already see your table populated with values from your dictionary then you can rule out data source and delegate as being the problem. i.e. your storyboard connections are working.
Your code looks fine to me. the only difference I see is I usually define my table like this. Try this and see if it helps.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//NSLog(#"Inside cellForRowAtIndexPath");
static NSString *CellIdentifier = #"Cell";
// Try to retrieve from the table view a now-unused cell with the given identifier.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// If no cell is available, create a new one using the given identifier.
if (cell == nil)
{
// Use the default cell style.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Your code here
// ....
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"menuCell"];
This will return nil in case there was never a cell created.
so checking if cell is nil is mandatory and if so, you need to create a cell.
static NSString *CellIdentifier = #"menuCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
as you are using storyboard you can alternatively use
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
for prototype cells. Make sure you use the same identifier in the storyboard and that you registered your the cell's class
- (void) viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"menuCell"];
}