CoreDataBooks Example - Start Cells at Index 1? - iphone

Im working with the CoreDataBooks example project from Apple and I want to have a custom cell at indexPath 0 in my tableview and then have my core data fetched results start from index 1.
I have tried some different solutions but can't get it working, if you have any ideas it would due appreciated thanks.
If you want to know what I have tried and failed let me know. What I want to achieve seems simple, just start the fetched results at cell 1 rather than 0.
Edit 2:
All my UITableViewDataSource and configureGuestCell code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0)
{
static NSString *CellIdentifier = #"statsCell";
GuestStatsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[GuestStatsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Configure the cell.
[self configureStatsCell:cell];
return cell;
}
if (indexPath.row > 0)
{
static NSString *CellIdentifier = #"guestCell";
customGuestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[customGuestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell.
[self configureGuestCell:cell atIndexPath:indexPath];
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
int cellHeight;
if (indexPath.row == 0)
{
cellHeight = 240;
}
else
{
cellHeight = 44;
}
return cellHeight;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[fetchedResultsController sections] count];
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (void)configureGuestCell:(customGuestCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
//Configure the cell to show the Guests first and last name and other details
GuestInfo *guest = [fetchedResultsController objectAtIndexPath:indexPath];
cell.guestNameLbl.text = [NSString stringWithFormat:#"%# %#", guest.firstName, guest.lastName];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the managed object.
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
[context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];
NSError *error;
if (![context save:&error])
{
// Update to handle the error appropriately.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1); // Fail
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create and push a detail view controller.
guestListDetailViewController *detailViewController = [[guestListDetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
GuestInfo *selectedGuest = (GuestInfo *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
// Pass the selected book to the new view controller.
detailViewController.guest = selectedGuest;
[self.navigationController pushViewController:detailViewController animated:YES];
}

Fixed code:
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects] +1;
}
- (void)configureGuestCell:(customGuestCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *path = [NSIndexPath indexPathForRow:(indexPath.row - 1) inSection:indexPath.section]
//Configure the cell to show the Guests first and last name and other details
GuestInfo *guest = [fetchedResultsController objectAtIndexPath:path];
cell.guestNameLbl.text = [NSString stringWithFormat:#"%# %#", guest.firstName, guest.lastName];
}
Small explanation:
you should return a one row more in numberOfRowsInSection, but, to prevent errors, row number should be decremented before calling [NSFetchedResultsController objectAtIndexPath].

Add 1 to the indexPath.row value....?!

For this to work you also need to edit the -tableView: numberOfRowsInSection: to return (realRows + 1) as well.
Likewise you will want to decrement the row by one whenever you are referencing your NSFetchedResultsController | NSArray which I suspect is in your configureCell:atIndexPath:
Anywhere you want/need to touch the data source you will need to adjust for that row either by incrementing or decrementing.
Response to OP
Don't change the NSIndexPath, there is no need. Adjust the index in your -configureCell: atIndexPath: or anywhere else that touches that index value:
-(void)configureCell:(id)cell atIndexPath:(NSIndexPath*)indexPath
{
NSInteger finalIndex = [indexPath row] - 1;
NSIndexPath *newPath = [NSIndexPath indexPathForRow:finalIndex inSection:[indexPath section]];
id object = [[self myNSFRC] objectAtIndexPath:newPath];
//Continue configuring your cell
}
Obviously if you are using an array then don't bother creating a new NSIndexPath.

Related

How to get display data in UITableView Section tables with single Array

I have data on a server which I want to show in the a tableView.
The problem is that I want to show data based on categories so I have array categories which has categories which will be section titles and inside them there data so for display the data in section I have to declare Array.
e.g. If there are three categories then we have to make three array to populate data but what if there are more categories as categories are dynamic and come from server.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [categoryArray count] ;
}
And how to set title for section title, as it is in category array, so if it is section one by one in array.
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSLog(#"Number of Sections");
if(section == 0)
return #"Sales";
if(section == 1)
return #"Soft Skills";
}
How to show data in tableView cells may I create arrays for all the categories?
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section==0)
{
appDelegate = (MultipleDetailViewsWithNavigatorAppDelegate *)[[UIApplication sharedApplication] delegate];
int count=[resultArray count];
NSLog(#"resultArry Row Counts is %d",count);
return [resultArray count];
}
else{
appDelegate = (MultipleDetailViewsWithNavigatorAppDelegate *)[[UIApplication sharedApplication] delegate];
int count=[resultArrayOne count];
NSLog(#"resultArry Row Counts is %d",count);
return [resultArrayOne count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Table Cell Data");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if (indexPath.section==0) {
appDelegate = (MultipleDetailViewsWithNavigatorAppDelegate *)[[UIApplication sharedApplication] delegate];
ObjectData *theCellData = [resultArray objectAtIndex:indexPath.row];
NSString *cellValue =theCellData.sub_Category;
cell.font=[UIFont fontWithName:#"Helvetical Bold" size:14];
NSLog(#"Cell Values %#",cellValue);
cell.textLabel.text = cellValue;
return cell;
}
else {
appDelegate = (MultipleDetailViewsWithNavigatorAppDelegate *)[[UIApplication sharedApplication] delegate];
ObjectData *theCellData = [resultArrayOne objectAtIndex:indexPath.row];
NSString *cellValue =theCellData.sub_Category;
cell.font=[UIFont fontWithName:#"Helvetical Bold" size:14];
NSLog(#"Cell Values %#",cellValue);
cell.textLabel.text = cellValue;
return cell;
}
}
Since getting the categories from the server does not seem to be your question I base my answer on pre filled arrays for a better visualization.
NSMutableArray *categories = #[#"Cat1", #"Cat2"];
// creata a dictionary with all the array for the categorie rows
NSMutableDictionary *rowDict = #{#"Cat1":#[#"Cat1Row1",#"Cat1Row2",#"..."],
#"Cat2":#[#"Cat2Row1", #"Cat2Row2",#"..."]
Key to this solution is that you use the category string as key for the dictionary.
You can now access the title like this
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return categories[section];
}
And access your rows like this
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ...
// create or deque a cell like you normally would do
// now configure the cell
cell.textLable.text = [rowDict[categories[indexPath.section]] objectAtIndex:indexPath.row]
}
use
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [categoryArray objectAtindex:section];
}
for section title.
likewise, store the values for each categories in a nsmutable array NSDictionary and display the data for each category in uitableviewcell.
Try the below code. It'll solve your problem :
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [categoryArray objectAtIndex:section];
}
EDIT :
First Create a model data class to store data of your categories.
Use this model class to feel your numberOfRowsInSection and cellForRowAtIndexPath delegate function.
Instead of creating different-different array for each category. Store this array in one model class. It'll be easy to handle.

NSUserDefaults + NSMutableArray -> Storing 2 arrays and display in tableview

I have just implementet a bookmark/favorites function in my app, favorites from a tableview, with the following code, using NSUserDefaults. The cell has 2 labels, the name of the item and a price - stored in the Arrays - theArray and thePriceArray -> like this:
NSIndexPath *indexPath = [_ListTableView indexPathForCell:(UITableViewCell *) [[sender superview] superview]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *OrderList = [[defaults objectForKey:ORDER_KEY] mutableCopy];
if (!OrderList) OrderList = [NSMutableArray array];
[OrderList addObject:[theArray objectAtIndex:indexPath.row]];
[OrderList addObject:[thePriceArray objectAtIndex:indexPath.row]];
[defaults setObject:OrderList forKey:ORDER_KEY];
[defaults synchronize];
I am now adding the two arrays theArray & thePriceArray, to the NSMutableArray.I now want to show these information (the information from the arraies) in another tableview. I do this like so:
In My viewDidAppear:
NSUserDefaults *defaults = kSettings;
NSMutableArray *theOrderList = [NSMutableArray arrayWithArray:[defaults objectForKey:ORDER_KEY]];
And to show the contents in the tableview:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [theOrderList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"TheTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [theOrderList objectAtIndex:indexPath.row];
return cell;
}
This is almost working as I want, the contents of theArray and thePriceArray is shown, but in a long list like so:
I want the "key and the value" to be in one cell, so the price and the item name in one cell (Hat - 30) and not seperate, how can I do that? I have tried to use a NSDictionary, but without luck and can I use NSDictionary for this?
You can create two new arrays for favItem and favPrize. Just add your favorite Items to favItem Array and add favorite Prizes to favPrize Array. Now use these arrays to set the labels and detailLabels of your Tableview like :
cell.textLabel.text = [favItems objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [favPrize objectAtIndex:indexPath.row];
Keep both array theArray and thePriceArray seperate and use one as your main array for data source of tableView.
Note : add data from NSUserDefault to respective array.
Now method will be :
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [theArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"TheTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubTile reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [theArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [thePriceArray objectAtIndex:indexPath.row];
return cell;
}
You can simply do it using the following code:
NSString *label = [NSString stringWithFormat:#"%# %#",[theOrderList objectAtIndex:(indexPath.row * 2)],[theOrderList objectAtIndex:(indexPath.row * 2)+1]
cell.textLabel.text = label;
And also change your numberOfRowsInSection like:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [theOrderList count]/2;
}

Modify multiple rows on uitableview on view load

I have a UITableView that should have 33 rows. Each row represents a specific time slot in a day. When the view that holds the table view loads, I need it to populate each row accordingly.
I have an array of reservation objects that gets passed to the view. Each reservation contains a slot number, a reservation name and the duration of the reservation in slots.
What is the best way to populate the table, I am currently iterating through the array of reservations in the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method.
This is not giving me the results or the behavior I am expecting. The performance is extremly poor as it keeps iterating through loops and cells that shouldn't be blue are blue after scrolling. What is the best way to approach this? I have included the code below.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 33;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSString *timeStamp = [NSString stringWithFormat:#"%.2f", (indexPath.row + 14.0 ) / 2.0];
timeStamp = [timeStamp stringByReplacingOccurrencesOfString:#".50" withString:#":30"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%#: ", timeStamp];
for (Reservation *temp in bookingsArray) {
if ((temp.slotNumber - 1) == indexPath.row) {
cell.textLabel.text = [NSString stringWithFormat:#"%#: %#", timeStamp, temp.reservationName];
cell.contentView.backgroundColor = [UIColor blueColor];
}
for (NSNumber *tempNo in temp.slotIdentifiers) {
if ([tempNo intValue] -1 == indexPath.row) {
//cell.textLabel.text = [NSString stringWithFormat:#"%#: Booked", timeStamp];
cell.contentView.backgroundColor = [UIColor blueColor];
}
}
}
return cell;
}
UPDATE
Trying the following gives me strange behaviour where all the cells turn blue after I start scrolling.
- (void)viewDidLoad
{
[super viewDidLoad];
bookManager = appDelegate.bookingManager;
bookingsArray = [[NSArray alloc] initWithArray:[bookManager getBookingsForCourt:1 onDate:[NSDate date]]];
namesArray = [[NSMutableDictionary alloc] init];
slotIndexSet = [NSMutableIndexSet indexSet];
for (int c = 0; c < 33; c++) {
[namesArray setObject:#"Available" forKey:[NSNumber numberWithInt:c]];
}
for (Reservation *temp in bookingsArray) {
[namesArray setObject:temp.reservationName forKey:[NSNumber numberWithInt:temp.slotNumber]];
for (NSNumber *slotNo in temp.slotIdentifiers) {
[slotIndexSet addIndex:[slotNo intValue] + 1];
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSString *timeStamp = [NSString stringWithFormat:#"%.2f", (indexPath.row + 14.0 ) / 2.0];
timeStamp = [timeStamp stringByReplacingOccurrencesOfString:#".50" withString:#":30"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%#: ", timeStamp];
cell.textLabel.text = [namesArray objectForKey:[NSNumber numberWithInt:indexPath.row]];
if ([slotIndexSet containsIndex:indexPath.row]) {
cell.contentView.backgroundColor = [UIColor blueColor];
}
return cell;
}
You need to do two things to speed this up:
Convert bookingsArray to a bookingBySlotNumber array in such a way that the object at index i has slotNumber - 1 equal to i. You can do it by iterating over the original bookings array when you receive it.
Create a NSIndexSet called isBookedBySlotNumber containing indexes of items that have been booked. You can prepare it by going through all Reservation.slotIdentifiers, and marking the indexes of isBookedBySlotNumber for items that have been booked.
With these two pre-processed items in place, you can eliminate the nested loops altogether: the outer one will be replaced by a lookup in bookingBySlotNumber, and the inner one - by a loopup in isBookedBySlotNumber.

Deleting records in UITableViewController throws error

Problem: When I click the delete button for a given table/section row, i get the following error: "*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'"
From other posts I have read about this symptom, I gather I am suppose to be manually removing an element in my datasource array, but not sure how to access the section's array inside this method:
// COMMIT EDITING STYLE
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"indexPath: %#", indexPath);
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates]; // throws error here
[tableView reloadData];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
I think the complication for this situation arises due to the fact that the plist (FormEntries.plist) I am pulling data from holds user input for all sorts of things all through out my app, thus I am having to call and filter it for every section. This works fine to populate the UITableView and all of it's sections, but because a new filtered array is being created for and inside each section, I'm not sure how to ever access it again in order to remove the element, thus rectifying the above error message. Here is how I am loading the data for each table section:
// CELL FOR ROW AT INDEXPATH
- (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];
}
NSNumber *numScreenId = [[arrayOfModulesScreens objectAtIndex: indexPath.section] objectForKey: #"id"];
NSMutableArray *arrayRecords = [epFrameWork selectPlist: #"FormEntries" filterByKey: #"screen_id" keyValue:numScreenId];
NSString *strTitle = [[arrayRecords objectAtIndex: indexPath.row] objectForKey: #"storage_string"];
cell.textLabel.text = strTitle;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-- Not sure if this will help diagnose things, but here it is none the less ---
// TITLE FOR HEADER IN SECTION
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[arrayOfModulesScreens objectAtIndex: section] objectForKey: #"screen_title"];
}
// NUMBER OF SECTIONS IN TABLE VIEW
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrayOfModulesScreens count];
}
// NUMBER OF ROWS IN SECTION
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSNumber *numScreenId = [[arrayOfModulesScreens objectAtIndex: section] objectForKey: #"id"];
NSMutableArray *arrayRecords = [epFrameWork selectPlist: #"FormEntries" filterByKey: #"screen_id" keyValue:numScreenId];
int rowCount = [arrayRecords count];
return rowCount;
}
What is the best approach to handle this situation or to resolve the above posted error message?
-- UPDATE --
So here is how I'm trying to identify which plist record to delete, assuming that's what I need to do to resolve the original error:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
int g = indexPath.row;
int count = -1;
UITableViewCell *tvc = [[UITableViewCell alloc] init];
for(id element in tableView.subviews) {
if([element isKindOfClass:[UITableViewCell class]]) {
count +=1;
NSLog(#"g: %d - count: %d", g , count);
if(count == g) {
tvc = element;
NSLog(#"tvc: %# - UID: %# - g: %d - count: %d", tvc, tvc.detailTextLabel.text, g , count);
}
}
}
My logic here was to set a hidden unique identifier on tvc.detailTextLabel.text in the cellForRowAtIndexPath method, which in turn would let me know which record from the plist to filter and delete by calling [array removeObjectAtIndex:uid] where array is my filtered plist array. Only problem now is that tvc in the NSLog always returns the record at index 0, not the row that holds the delete button I click.
NSLog returns: tvc: < UITableViewCell: 0x713e2c0; frame = (0 30; 320 44); text = 'Church A'; autoresize = W; layer = < CALayer: 0x7113e70 > > - UID: -237206321 - g: 3 - count: 3. So why would tvc return the index 0 when it was index 3 I clicked the delete button?
Is this just becoming a clustered mess or is there a cleaner solution? But ya, still stumped.
This error most definitely relates to your mishandling the data that you are trying to load to your table. I found that the easiest and safest way to handle modifying table content is to do something along those lines, with the necessary adjustments (within tableView:commitEditingStyle:)
//REMOVE A CELL FROM A SECTION
[yourTable beginUpdates];
[yourTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom];
[yourTable endUpdates];
[yourTable reloadData];
In addition you need to make sure that your array is properly updated to have the changes reflected in the table.
This is how I was finally able to resolve the issue:
I changed all of this crap:
int g = indexPath.row;
int count = -1;
UITableViewCell *tvc = [[UITableViewCell alloc] init];
for(id element in tableView.subviews) {
if([element isKindOfClass:[UITableViewCell class]]) {
count +=1;
NSLog(#"g: %d - count: %d", g , count);
if(count == g) {
tvc = element;
NSLog(#"tvc: %# - UID: %# - g: %d - count: %d", tvc, tvc.detailTextLabel.text, g , count);
}
}
}
to one simple line:
UITableViewCell *cell = [[self tableView] cellForRowAtIndexPath:indexPath];
This allowed me to identify the cell I was working with. So my final code that worked looks like this:
// COMMIT EDITING STYLE
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
UITableViewCell *cell = [[self tableView] cellForRowAtIndexPath:indexPath];
[epFrameWork deleteRecordFromPlist:#"FormEntries" uid:cell.detailTextLabel.text];
[tableView reloadData];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
-(void) deleteRecordFromPlist:(NSString *)plist uid:(NSString *)uId {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *tmpFileName = [[NSString alloc] initWithFormat:#"%#.plist", plist];
NSString *path = [documentsDirectory stringByAppendingPathComponent:tmpFileName];
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSDictionary *dict = [[NSDictionary alloc] init];
NSString *tmpUid;
for(int i=0; i < [array count]; i++) {
dict = [array objectAtIndex:i];
tmpUid = [dict valueForKey:#"uid"];
if([tmpUid isEqualToString:uId]) {
[array removeObjectAtIndex:i];
[array writeToFile:path atomically:YES];
}
}
}

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