I have a problem which seems to be very simple. I have a UITableView in my APP. In numberOfSectionsInTableView: I set the count of sections to 2. However the tableView shows only the first section. I tried to make the two sections show same contents by writing same codes in both sections, but useless. Then I found a similar question here. But its correct answer is about frame and my layout is a very simple UITableViewController. At last I tried to add NSLog to the three methods. The result is: For case section 1, numberOfSectionsInTableView: and numberOfRowsInSection: are called but cellForRowAtIndex isn't called. I wonder how to explain this.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
int count;
switch (section) {
case 0:
count = [_objectArray count];
break;
case 1:
NSLog(#"section called"); // This line is logged
count = 1;
default:
count = 0;
break;
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"myCellIdentifier";
static NSString *basicCellIdentifier = #"myBasicCellIdentifier";
switch ([indexPath section]) {
case 0: {
TableViewStoryCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
// Configure the cell...
int theIndex = [indexPath row];
MyObject *theObj = [_objectArray objectAtIndex:theIndex];
cell.object = theObj;
return cell;
break;
}
case 1: {
NSLog(#"cell called"); //this line isn't logged
for (int i = 0; i < 50; i++) {
NSLog(#"hahaha");
}
MyBasicViewStoryCell *cell = [tableView dequeueReusableCellWithIdentifier:basicCellIdentifier forIndexPath:indexPath];
return cell;
break;
}
default: {
for (int i = 0; i < 50; i++) {
NSLog(#"hahaha1");
}
return nil;
break;
}
}
}
Put break in switch case. You missed break in case 1: so the default will also execute. Thus the count become zero count = 0. Since numberOfRowsInSection: returns zero, cellForRowAtIndexPath: will not call. So put break in case 1: of numberOfRowsInSection:
switch (section) {
case 0:
count = [_objectArray count];
break;
case 1:
NSLog(#"section called"); // This line is logged
count = 1;
break; // Here
default:
count = 0;
break;
}
You don't have a break after you set the count for section 1 and it falls through and is set to zero.
case 1:
NSLog(#"section called"); // This line is logged
count = 1;
break; // always put break!
cellForRowAtIndexPath won't be called if numberOfRowsInSection is not returning a value that is >=1.
Related
i try many thing but it displaying cells
i have add delegate and datasource
tableview.dataSouce =self;
tableview.Delegate = self;
func cell for row height
return 44;
i dont know why table view is not displaying
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
int count = (int)_dict_contact.count;
return count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case 0:
{
NSArray *arr_email =[_dict_contact objectForKey:#"u_email"];
int count = (int)arr_email.count;
return count;
}
break;
case 1:
{
NSArray *arr_phone =[_dict_contact objectForKey:#"u_phone"];
return arr_phone.count;
}
break;
}
return 0;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MultipleContCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell)
{
cell = [[MultipleContCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
switch (indexPath.section) {
case 0:
{
NSArray *arr_email =[_dict_contact objectForKey:#"u_email"];
cell.detail_lbl.text =[arr_email objectAtIndex:indexPath.row];
return cell;
}
break;
case 1:
{
NSArray *arr_phone =[_dict_contact objectForKey:#"u_phone"];
cell.detail_lbl.text =[arr_phone objectAtIndex:indexPath.row];
return cell;
}
break;
}
return cell;
}
but after trying too much then also my cellForRowAtIndexPath not called
You need to call registerNib: forCellReuseIdentifier or registerClass:forCellReuseIdentifier for MultipleContCell inside viewdidload. For example:
[_yourTableView registerNib:[UINib nibWithNibName:#"MultipleContCell" bundle:nil] forCellReuseIdentifier:#"MultipleContCell"];
Check :
1) The numberOfSectionsInTableView is not returning 0.
2)UITableview frame is correct because cellForRowAtIndexPath would not be called is when the size or positioning of the table does not require any rows to be displayed.
Make sure that
numberOfSectionsInTableView returns value > 0
numberOfRowsInSection returns value > 0
UITableView frame > 0
You must declare your ViewController as UITableViewDelegate and UITableViewDataSource. Something like this:
#interface MyViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
Is it possible to get the section count for the respective selected row in a UITableView
yes you can check for section with
indexPath.section
If you have NSIndexPath you can get row by
indexPath.row
or section by
indexPath.section
Try the following sample code:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 5;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger rows = 0;
switch (section) {
case 0:
rows = 7;
break;
case 1:
rows = 21;
break;
case 2:
rows = 3;
break;
case 3:
rows = 1;
break;
case 4:
rows = 5;
break;
default:
break;
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CELL" forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:#"section : %ld & rows : %ld",(long)indexPath.section,(long)indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//This will print which row of which section is clicked
NSLog(#"section : %ld & rows : %ld",(long)indexPath.section,(long)indexPath.row);
}
which is right !
NSArray <NSIndexPath *>*rows = [tableView indexPathsForSelectedRows];
I solved what i was looking for. I wanted to get all the section number for the respective selected rows in it, on the button click.
I used
NSArray *paths = [self.tableView indexPathsForSelectedRows];
Hello I have implemented example Expand Table
-(void)sectionButtonTouchUpInside:(UIButton*)sender
{
// sender.backgroundColor = [UIColor greenColor];
[self.tableView beginUpdates];
int section = sender.tag;
bool shouldCollapse = ![collapsedSections containsObject:#(section)];
if (shouldCollapse)
{
int numOfRows = [self.tableView numberOfRowsInSection:section];
NSArray* indexPaths = [self indexPathsForSection:section withNumberOfRows:numOfRows];
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
[collapsedSections addObject:#(section)];
}
else
{
int numOfRows = 0 ;
switch (section)
{
case 0:
numOfRows = (int)aArray.count;
break;
case 1:
numOfRows = (int)bArray.count;
break;
case 2:
numOfRows = (int)cArray.count;
break;
case 3:
numOfRows = (int)dArray.count;
break;
}
NSArray* indexPaths = [self indexPathsForSection:section withNumberOfRows:numOfRows];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
[collapsedSections removeObject:#(section)];
}
[self.tableView endUpdates];
}
My program crashed in above code with this message:
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'Invalid update: invalid
number of rows in section 2. The number of rows contained in an
existing section after the update (1) must be equal to the number of
rows contained in that section before the update (1), plus or minus
the number of rows inserted or deleted from that section (0 inserted,
1 deleted) and plus or minus the number of rows moved into or out of
that section (0 moved in, 0 moved out).
Update
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(![_collapsedSections containsObject:#(section)])
{
return 0;
}
else
{
int count = 0;
switch (section)
{
case 0:
count = (int)aArray.count;
break;
case 1:
count = (int)bArray.count;
break;
case 2:
count = (int)cArray.count;
break;
case 3:
count = (int)dArray.count;
break;
}
return count;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section == 0)
{
return [__collapse containsObject:#(section)] ? 0 : [self.section1 count];
}
else if(section == 1)
{
return [__collapse containsObject:#(section)] ? 0 : [self.section2 count];
}
else if(section == 2)
{
return [__collapse containsObject:#(section)] ? 0 : [self.section3 count];
}
else
{
return 0;
}
}
Modify this method like above..
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int count = 0;
switch (section)
{
case 0:
count = (int)aArray.count;
break;
case 1:
count = (int)bArray.count;
break;
case 2:
count = (int)cArray.count;
break;
case 3:
count = (int)dArray.count;
break;
}
return count;
}
Try this..
For Ur Code..Initially ur rows are 0. So, After u click event methods try to insert ur array no.of.rows.. Thats causing error.
i am developing an iPhone app with tableview that act as a form with different sections. i also have 3 custom cell that contain Text Field, Segment Control and UISwitchView. my problem is that when i pressed on of the Switches or type some text in one of the textField, the same state of the Switch or text of the text Field reappear in different row and in different section.
Here is some images and part of my code to describe my problem:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 0;
switch (section) {
case 0:
rows = 5;
break;
case 1:
rows = 11;
break;
case 2:
rows = 9;
break;
default:
break;
}
return rows;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
// init cell
switch (indexPath.section) {
case 0:
if (indexPath.row>=0 && indexPath.row<=3)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"text_field_cell"];
}
else if (indexPath.row == 4)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"segment_cell"];
}
break;
case 1:
if (indexPath.row >=0 && indexPath.row <= 9)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"switch_cell"];
}
else if (indexPath.row == 10)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"text_field_cell"];
}
break;
case 2:
if (indexPath.row >=0 && indexPath.row <= 6)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"switch_cell"];
}
else if (indexPath.row >=7 && indexPath.row <=8)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"text_field_cell"];
}
break;
default:
break;
}
// init all text ..
return cell;
}
I would implement -tableView:willDisplayCell:forRowAtIndexPath: to set your cells to a correct state for each row.
I am using paging with uitableview. I have array of 40 objects. In the numberofrowsinasection method, I am returning 10 rows. Its mean total number of pages is four. Within the pagecontrol method, I am implementing the paging. When I like
-(ibaction) pagecontrol:
{
if (pagecontrol.currentpage == 0)
{
for (int i=0; i<10; i++ )
{
cell.textlabel.text = [objectarray objectatindex:i];
}
}
if (pagecontrol.currentpage == 1)
{
for (int i=10; i<19; i++ )
{
cell.textlabel.text = [objectarray objectatindex:i];
}
}
if (pagecontrol.currentpage == 2)
{
for (int i=20; i<29; i++ )
{
cell.textlabel.text = [objectarray objectatindex:i];
}
}
if (pagecontrol.currentpage == 3)
{
for (int i=30; i<39; i++ )
{
cell.textlabel.text = [objectarray objectatindex:i];
}
}
}
But I found a strange result in uiableview. Is it correct? Where am I doing the mistake in this pagecontrol method?
Do you always have exactly 40 rows or could there be less?
The code you posted starts with a missing method parameter. There should be either no colon or a parameter after the colon (with a data type).
The code you posted suffers from several problems. The biggest issue is you set the text of the same cell 10 times. You need to set the text of 10 cells, one time each.
Regardless of that, you are going about this all wrong. Replace your posted method with this:
-(IBAction)pagecontrol:(UIPageControl *)pageControl {
[self.tableView reloadData];
}
Then, in your tableView:cellForRowAtIndexPath: method you should do the following:
- (void)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableView *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
int base = pagecontrol.currentPage * 10;
int index = base + indexPath.row;
NSString *text = objectArray[index];
cell.textLabel.text = text;
return cell;
}
This is in addition to your numberOfSectionsInTableView: and tableView:numberOfRowsInSection: methods.
That's all you need.
BTW - case matters. Don't type everything in lowercase. Type it in properly with the proper case.
You are using a constant row in paging to use the section in tableview. It differentiates the rows in the page,
like this:
Set the number of sections in tableview:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 4;
}
// Set rows in section
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch(section){
case 0:
return 10;
break;
case 1:
return 10;
break;
.....
.....
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *FirstLevelCell= #"FirstLevelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FirstLevelCell] autorelease];
}
switch([indexPath section]){
case 0:
{
//Add your code
}
break;
case 1:
{
//Add your code
}
break;
.........
.........
.........
.........
.........
}
}
//Reload table view
[self.tableView reloadData];