Error in getting the title for section - iphone

I am creating an expense tracker kind of application.
My requirement is to get the date in the section header and the expenses added on that date in the table View. I tried the following code but its not working.
-(IBAction)bydate:(id)sender
{
[self.byDateArray removeAllObjects];
[self.byDateCountArray removeAllObjects];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
for(NSManagedObject *info in self.listOfExpenses){
NSString *compareDates = [dateFormatter stringFromDate:[info valueForKey:#"date"]];
BOOL isAvail = NO;
for (int i = 0; i<[self.byDateArray count]; i++){
if([compareDates isEqualToString:[self.byDateArray objectAtIndex:i]])
{
isAvail = YES;
}
}
if(!isAvail)
[self.byDateArray addObject:compareDates];
}
int count = 0;
for (int i = 0 ; i < [self.byDateArray count] ; i ++){
NSString *compareDates = [self.byDateArray objectAtIndex:i];
for(NSManagedObject *info in self.listOfExpenses){
if([compareDates isEqualToString:[dateFormatter stringFromDate:[info valueForKey:#"date"]]])
{
count++;
}
}
[self.byDateCountArray addObject:[NSNumber numberWithInt:count]];
count = 0;
}
self.byDateTab.hidden = NO;
self.byDateTab.frame = CGRectMake(0, 123, 320, 244);
[self.view addSubview:self.byDateTab];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if(tableView == self.byDateTab)
return [self.byDateArray count
return 3;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int rows;
if(tableView == self.byDateTab)
rows = [[self.byDateCountArray objectAtIndex:section] intValue];
return rows;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CellIdentifier"]autorelease];
if (tableView == self.byDateTab)
{
for(int i = 0; i < [self.byDateCountArray count];i++)
{
if(indexPath.section == 0)
{
NSManagedObject *records = nil;
records = [self.listOfExpenses objectAtIndex:indexPath.row];
self.firstLabel.text = [records valueForKey:#"category"];
self.secondLabel.text = [records valueForKey:#"details"];
NSString *amountString = [NSString stringWithFormat:#"%#",[records valueForKey:#"amount"]];
self.thirdLabel.text = amountString;
}
else if (indexPath.section == i)
{
int rowCount = 0;
for(int j=0; j<indexPath.section; j++)
{
rowCount = rowCount + [[self.byDateCountArray objectAtIndex:j]intValue];
}
NSManagedObject *records = nil;
records = [self.listOfExpenses objectAtIndex:(indexPath.row + rowCount) ];
self.firstLabel.text = [records valueForKey:#"category"];
self.secondLabel.text = [records valueForKey:#"details"];
NSString *amountString = [NSString stringWithFormat:#"%#",[records valueForKey:#"amount"]];
self.thirdLabel.text = amountString;
}
}
}
But am getting the SIGABRT error in this line
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.byDateArray objectAtIndex:section];
}
I am getting the following error in the NSlog
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index 2 beyond bounds for empty array'

the problem is here
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if(tableView == self.byDateTab)
return [self.byDateArray count];
//why crashed at index 2, because here is 3
return 3;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.byDateArray objectAtIndex:section];
}
it crash at another tableview that not "self.byDateTab"
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(tableView == self.byDateTab)
{
return [self.byDateArray objectAtIndex:section];
}
else
{
//you should deal with other tableview
// it crashed here
}
}
or just disable other tableview's section header
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if(tableView == self.byDateTab)
return [self.byDateArray count];
//i don't see other tableviews how to work, so if you do this, the code will work
//then you should look back to the solution above
return 0;
}

According to the error your self.byDateArray does not have any object at index 2 , so please check the contents of your array.

Your byDateArray seems to be empty.
What are doing with [self.byDateArray removeAllObjects];?

As mentioned above, the problem is in adding objects to you self.byDateArray
Maybe self.byDateArray is not initialized?
Please, make NSLog(#"self.byDateArray: %#",self.byDateArray) just before [self.byDateArray removeAllObjects]; in your -(IBAction)bydate:(id)sender method.

This is means a
section
value is bigger than
self.byDateArray
count.
Try add this in 1st code line:
NSLog(#" %# ", self.byDateArray);
in -(NSString *)tableView: function for see a content of array.

Related

Array out of bounds error when using UISearchDisplayController

I have a UISearchDisplayController on a UITableView. The UITableView grabs JSON data from a server, breaks it down, and an object class takes that data and creates objects. It adds the Objects to a Mutable array to then use as the datasource for the table.
There is also another Mutable array used as the 'filtered' objects.
It's declared like so:
self.filteredItems = [NSMutableArray arrayWithCapacity:[self.items count]];
When I try to search the table I get this error:
Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
This is the code I'm using to do the filtering, which I found after going through a bunch of tutorials, I can't use NSPredicate because it seems the return function returns an NSArray, and I have an NSMutableArray, which I can not change because i'm not declaring the objects statically.
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
/*
Update the filtered array based on the search text and scope.
*/
[self.filteredItems removeAllObjects];
for (Update *update in items)
{
if ([scope isEqualToString:#"Serial Number"]) {
NSComparisonResult result = [[update Serial_Number] compare:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame){
[filteredItems addObject:update];
}
} else if ([scope isEqualToString:#"Ticket Number"]) {
NSComparisonResult result = [[update Ticket_Number] compare:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame){
[filteredItems addObject:update];
}
} else if ([scope isEqualToString:#"Customer"]) {
NSComparisonResult result = [[update Customer] compare:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame){
[filteredItems addObject:update];
}
}
}
}
Not too sure what I'm doing wrong, I've never tried to implement this control before.
I actually ran break points, I can see that the objects are getting added to the filtered array, but then suddenly it crashes.
If you need any other part of the code to help me please let me know.
Thank you!
Edit:
Here's the delegate methods:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (updatesTableView == self.searchDisplayController.searchResultsTableView) {
return [self.filteredItems count];
} else {
return [self.items count];
}
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
Update *update = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
update = [filteredItems objectAtIndex:indexPath.row];
} else {
// Configure the cell...
update = [items objectAtIndex:indexPath.row];
}
[[cell textLabel] setText:[update Serial_Number]];
[[cell detailTextLabel] setText:[NSString stringWithFormat:#"Customer: %#", [update Customer]]];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
The normal table displays just fine as well as their detail views.
In your delegate methods you have in 'numberOfRows':
if (updatesTableView == self.searchDisplayController.searchResultsTableView) {
then in 'cellForRowAtIndexPath':
if (tableView == self.searchDisplayController.searchResultsTableView) {
You're comparing different tables for determining the number of rows and then which array to get the data from.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [self.filteredItems count];
} else {
return [self.items count];
}
}

Insert rows to UITableView crash

Im developing an app, need to load some data in background , then show the data using UITableView.
Here are some codes,
loading data in background:
- (void)loadRelatedItems
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (NSString *mediaType in allMediaTypes)
{
[self performSelector:#selector(loadRelatedItems:) withObject:mediaType];
}
NSString *notificationName = [CommonFunction allRelatedItemsLoadedNotificationName];
[[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:self userInfo:nil];
[pool release];
}
- (void)loadRelatedItems:(NSString *)mediaType
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (NSString *keyword in _keywords)
{
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"%#&mediaType=%#&keyword=%#", API, mediaType, keyword]];
NSMutableArray *items = [CommonFunctions arrayFromURL:URL];
if ([items count] == 0) continue;
NSString *notificationName = [CommonFunction partialRelatedItemsLoadedNotificationName];
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:items, #"items", mediaType, #"mediaType", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:self userInfo:dic];
}
[pool release];
}
showing the data in UITableView:
- (void)didFinishLoadPartialRelatedItems:(id)sender
{
NSDictionary *dic = [sender userInfo];
NSString *mediaTypeString = [dic objectForKey:#"mediaType"];
NSMutableArray *items = [dic objectForKey:#"items"];
dispatch_async(dispatch_get_main_queue(), ^{
if ([_relatedItems count] == 0)
{
[_relatedItems setObject:items forKey:mediaTypeString];
[_tableView reloadData];
}
else
{
NSMutableArray *mediaTypeItems = [_relatedItems objectForKey:mediaTypeString];
if (mediaTypeItems)
{
// section exist
NSInteger section =[[[_relatedItems allKeys] sortedArrayUsingSelector:#selector(mediaTypeCompare:)] indexOfObject:mediaTypeString];
NSMutableArray *indexPaths = [NSMutableArray array];
for (NSMutableDictionary *item in items)
{
[mediaTypeItems addObject:item];
NSInteger newRow = [mediaTypeItems indexOfObject:item];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:newRow inSection:section];
[indexPaths addObject:newIndexPath];
}
[_tableView beginUpdates];
[_tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
[_tableView endUpdates];
}
else
{
// new section
[_relatedItems setObject:items forKey:mediaTypeString];
NSInteger section =[[[_relatedItems allKeys] sortedArrayUsingSelector:#selector(mediaTypeCompare:)] indexOfObject:mediaTypeString];
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section];
[_tableView beginUpdates];
[_tableView insertSections:indexSet withRowAnimation:UITableViewRowAnimationNone];
[_tableView endUpdates];
}
}
});
}
#pragma mark -
#pragma mark Table Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if ([_relatedItems count] == 0) {
return 1;
} else {
return [_relatedItems count];
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSArray *allTitles = [[_relatedItems allKeys] sortedArrayUsingSelector:#selector(mediaTypeCompare:)];
NSString *title = [allTitles objectAtIndex:section];
NSDictionary *allMediaTypeDisplayNames = [CommonFunction allMediaTypeDisplayNames];
return [allMediaTypeDisplayNames objectForKey:title];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([_relatedItems count] == 0) {
return 0;
}
NSArray *allTitles = [[_relatedItems allKeys] sortedArrayUsingSelector:#selector(mediaTypeCompare:)];
NSString *title = [allTitles objectAtIndex:section];
NSInteger rowsCount = [[_relatedItems objectForKey:title] count];
return rowsCount;
}
I'm very confused that it works fine some times, but some times it crashed with message:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1030
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (0) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).
What's the problem? please help.
Please make sure after updating, your number of sections should be equal to number of sections before the update.
As per your code :
the number of sections are defined as like this:
if ([_relatedItems count] == 0) {
return 1;
} else {
return [_relatedItems count];
}
and in this case you are creating new section right ?
else { // new section
[_relatedItems setObject:items forKey:mediaTypeString];
NSInteger section =[[[_relatedItems allKeys] sortedArrayUsingSelector:#selector(mediaTypeCompare:)] indexOfObject:mediaTypeString];
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section];
[_tableView beginUpdates];
[_tableView insertSections:indexSet withRowAnimation:UITableViewRowAnimationNone];
[_tableView endUpdates];
}
If you are creating new section then your [_relatedItems count] is increasing. So, please make sure after the inserting also your count should be same.
Right ?
Try This :
if ([_relatedItems count] == 0) {
return 1;
} else {
if([_relatedItems count]>previousCount)
return [_relatedItems count];
return previousCount;
}
when ever you are making any updates to the [_relatedItems]; then change update your previousCount also.. this will be solved
I think your problem is with the number of rows method in the datasource just do one thing define int noOfRows in your .h file .assign your table view array count with the noOfRows. noOfRows=[yourtableArray count];
then return noOfRows from table views numberOfRowsInSection method.
Add 1 to noOfRows if you insert row in the table.
Make noOfRows-- when you delete row from the table
You will not get this exception .Update your array as per your requirement.

indexPath.row Returns Random Cell TextLabel in didSelectRowAtIndexPath

I have a UITableView populated by a SQLite database. I added Section-based Grouping using the sectionIndexTitlesForTableView delegate method today and now when a Cell is selected, the String for indexPath.row is not the same as the text in the selected Cell.
My Code works like this.
I create an Array that holds the businesses from the SQLite database.
I sort that Array alphabetically.
I create an Array of letters of the Alphabet using only the letters of the Alphabet that businesses in the database begin with.
I use that Array, along with an NSPredicate to provide Grouped Header views which group the businesses by their first letter, alphabetically.
The Selected Row is written to the NSUserDefaults file, and a View Controller is pushed (iPhone), or an Observer is added for that key (iPad).
Unfortunately, since adding the header views, indexPath.row now returns a completely different string to that of the TextLabel of the selected Cell, and so a different Business' information is displayed.
Here are the important blocks of code for the main arrays.
- (void)viewDidLoad
{
// Lots of code...
arrayName = [[NSMutableArray alloc] init];
NameSet = [[NSMutableSet alloc] init];
sortedArray = [arrayName sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
alphabet = [[NSMutableArray alloc] init];
[alphabet addObject:#"{search}"];
for (int i=0; i<[sortedArray count]-1; i++)
{
char alphabetUni = [[sortedArray objectAtIndex:i] characterAtIndex:0];
NSString *uniChar = [NSString stringwithFormat:#"%c", alphabetUni];
if (![alphabet containsObject:uniChar])
{
[alphabet addObject:uniChar];
}
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [alphabet count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 0;
NSString *alpha = [alphabet objectAtIndex:section];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alpha];
businesses = [sortedArray filteredArrayUsingPredicate:predicate];
if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]){
rows = [self.searchResults count];
}
else {
rows = [businesses count];
}
return rows;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection (NSInteger)section
{
return [alphabet objectAtIndex:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSString *alpha = [alphabet objectAtIndex:indexPath.section];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alpha];
businesses = [sortedArray filteredArrayUsingPredicate:predicate];
if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]){
cell.textLabel.text =
[self.searchResults objectAtIndex:indexPath.row];
}
else{
NSString *cellValue = [businesses objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *selected = nil;
if (tableView == self.tableView)
{
selected = [businesses objectAtIndex:indexPath.row];
}
else if (tableView == searchDis.searchResultsTableView)
{
selected = [filteredData objectAtIndex:indexPath.row];
}
[def setObject:selected forKey:#"NameChoiceDetail"];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
[self performSegueWithIdentifier:#"NameDetailPush" sender:self];
}
}
// Please excuse my horribly written code. I've only been working with Objective-C for 4 months, and Programming for about 8 months. Any suggestions/optimisations will be duly noted.
Your table view uses sections but your implementation of tableView:didSelectRowAtIndexPath: doesn't evaluate the section of the index path. So the code is missing something.
Furthermore, I find that your use of the businesses variable (it's probably an instance variable) very strange. It is assigned a value in tableView:cellForRowAtIndexPath: but not in tableView:didSelectRowAtIndexPath: even though it is used there. So the outcome if the latter depends on what table cell was displayed last and as a consequence it depends on scrolling user interaction. That might be the reason why the outcome looks rather random.

UITableView insertRowsAtIndexPaths:

I have a Navigation Controller that contains a uitableview when I press on a row it pops a new view controller on the stack, which is used to display detail information in the detail view it makes a request from the server to get some response information then once the information is returned I use insertRowsAtIndexPaths: to display the information that is returned from the server.
This all works fine the first time, then when i press the back button and select a new row or the same row for viewing the detailed information once I the insertRowsAtIndexPaths: is called i get the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Here is the code for pushing the view on the stack:
VideoDetailViewController_iPhone *nextView = [[VideoDetailViewController_iPhone alloc] initWithNibName:#"VideoDetailViewController_iPhone" bundle:nil withVideo:rowData];
nextView.navController = navController;
[navController pushViewController:nextView animated:YES];
[nextView release];
Here is the code is executed once the information is returned from the server
- (void)fetchVideoDetail:(NSNotification *)notification {
hasLoadedResponses = YES;
NSArray *obj = (NSArray *)[notification object];
responses = [[obj valueForKey:#"responses"] mutableCopy];
//NSLog(#"RESPONSES: %#", responses);
if ([responses count] == 0) {
[tblView reloadData];
return;
}
NSMutableArray *indexes = [[NSMutableArray alloc] init];
int i = 0;
for (NSArray *x in responses) {
if (i > 0) {
//The reason for skipping the first one is because we will change that row once the table refreshes we just need to insert any rows after the first one.
[indexes addObject:[NSIndexPath indexPathForRow:i inSection:1]];
}
i++;
}
//NSLog(#"indexCount: %i", [indexes count]);
[tblView beginUpdates];
[tblView insertRowsAtIndexPaths:indexes withRowAnimation:UITableViewRowAnimationBottom];
[tblView endUpdates];
//[tblView reloadData];
}
Here is the tableView methods:
- (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.
if (section == 0) {
return 1;
} else {
if ([responses count] == 0) {
NSLog(#"numberofrowsinsection: 1");
return 1;
} else {
NSLog(#"numberofrowsinsection: %i", [responses count]);
return [responses count];
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
VideoCell *cell = (VideoCell *)[tableView dequeueReusableCellWithIdentifier:CellClassName];
if (cell == nil) {
NSArray *topLevelItems = [cellLoader instantiateWithOwner:self options:nil];
cell = [topLevelItems objectAtIndex:0];
}
if (indexPath.section == 0) {
cell.lblTitle.text = [data title];
cell.lblDescription.text = [data videoDescription];
} else {
if ([responses count] == 0) {
if (!hasLoadedResponses) {
cell.lblTitle.text = #"";
cell.lblDescription.text = #"";
} else {
//Responses have been loaded
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.lblTitle.text = #"No responses to this video";
cell.lblDescription.text = #"Be the first to respond by selecting the \"Set as Destination\" button above";
}
} else {
//Display the response information
cell.lblTitle.text = [[responses objectAtIndex:indexPath.row] valueForKey:#"title"];
cell.lblDescription.text = [[responses objectAtIndex:indexPath.row] valueForKey:#"description"];
}
}
return cell;
}
Your datasource and number of rows are out of sync. When you insert the row, you have to increase the number of rows in the section at the same time. In this case you would have to increase the count of your array responses, which you are using in your numberOfRowsInSection method.

When empty field comes, removed the row in the Grouped Table view in iPhone?

I have displayed the datas in grouped table view. The data's are displayed in the table view from XML parsing. I have 2 section of the table view, the section one has three rows and section two has two rows.
section 1 -> 3 Rows
section 2 - > 2 Rows.
Now i want to check, if anyone of the string is empty then i should remove the empty cells, so i have faced some problems, if i have removed any empty cell, then it will changed the index number. So how can i check, anyone of the field is empty?, Because some times more number of empty field will come, so that the index position will be change. So please send me any sample code or link for that? How can i achieve this?
Sample code,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0) {
if([userEmail isEqualToString:#" "] || [phoneNumber isEqualToString:#" "] || [firstName isEqualToString:#" "])
{
return 2;
}
else {
return 3;
}
}
if (section == 1) {
if(![gradYear isEqualToString:#" "] || ![graduate isEqualToString:#" "]) {
return 1;
}
else
{
return 2;
}
return 0;
}
Please Help me out!!!
Thanks.
As per my understanding, you dont want to add the row where data is empty, so ill suggest you should perpare the sections data before telling the table view about the sections and rows.
So, may be following code can help you..., i have tested it you just need to call the method "prepareSectionData" from "viewDidLoad" method and define the section arrays in .h file.
- (void) prepareSectionData {
NSString *userEmail = #"";
NSString *phoneNumber = #"";
NSString *firstName = #"";
NSString *gradYear = #"";
NSString *graduate = #"";
sectionOneArray = [[NSMutableArray alloc] init];
[self isEmpty:userEmail]?:[sectionOneArray addObject:userEmail];
[self isEmpty:phoneNumber]?:[sectionOneArray addObject:phoneNumber];
[self isEmpty:firstName]?:[sectionOneArray addObject:firstName];
sectionTwoArray = [[NSMutableArray alloc] init];
[self isEmpty:gradYear]?:[sectionTwoArray addObject:gradYear];
[self isEmpty:graduate]?:[sectionTwoArray addObject:graduate];
}
-(BOOL) isEmpty :(NSString*)str{
if(str == nil || [[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0)
return YES;
return NO;
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section == 0){
return [sectionOneArray count];
} else if (section == 1) {
return [sectionTwoArray count];
}
return 0;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
if(indexPath.section == 0){
cell.textLabel.text = [sectionOneArray objectAtIndex:indexPath.row];
} else if (indexPath.section == 1) {
cell.textLabel.text = [sectionTwoArray objectAtIndex:indexPath.row];
}
return cell;
}
#Pugal Devan,
Well, you can keep the data in one array, but the problem in that case is, you have to take care of array bounds and correct indexes for different sections. For each section indexPath.row will start from index 0, and if your data is in single array, you have to manage the row index by your self. But still if you want to keep it, you can do like:
int sectionOneIndex = 0;
int sectionTwoIndex = 3;
NSMutableArray *sectionArray = [[NSMutableArray alloc] initWithObjects:#"email", #"Name", #"address", #"zipCode", #"country", nil];
Above two integers represents the starting position of elements of your different sections. First 3 objects from the section Array are the part of section One, and last two objects are the part of section two. Now you need to return correct row count.
For that you may write:
if(section == 0) return [sectionArray count] - (sectionTwoIndex-1); //returns 3
else if(section == 1) return [sectionArray count] - sectionTwoIndex; //returns 2
OR if your count is static you may put constant values in return.
And at the time you read from array, you will just add this index in row value, which will return the correct position of your element for the current cell.
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
if(indexPath.section == 0){
cell.textLabel.text = [sectionArray objectAtIndex:indexPath.row + sectionOneIndex];
} else if (indexPath.section == 1) {
cell.textLabel.text = [sectionArray objectAtIndex:indexPath.row + sectionTwoIndex];
}
return cell;
}