How do I get a Row count from a UITableView - iphone

I have a tableview I'd like to customize based on how many rows it has.
If it has no rows, I'd like the background image to prompt the user to add content.
If it has 1 or more rows, I'd like it to have a different background image, in order to display the content.
I'm using a fetched results controller to populate my tableview, by the way.
Any ideas?

Well this is generally very easy to accomplish as you need only to have UITableView properly delegated to your ViewController with appropriate delegate methods included in your .m file.
Then you can anywhere get row count like this:
[tablePropertyName numberOfRowsInSection:SECTION_NUMBER];
where section number is 0 for first section, 1 for second, etc.

In Swift, you can get the UITableView rows count by
yourTableViewName.numberOfRows(inSection: Int)
example:
yourTableViewName.numberOfRows(inSection: 0) // returns rows count in section 0

I agree with Sixten Otto's answer.
[myFetchedResultsController.fetchedObjects count];
However there's more. Above line would return the number of objects regardless the sections. However if you would want to perform this on a table with multiple sections, you would have to call it the following way.
[[myFetchedResultsController.sections objectAtIndex:<section>] numberOfObjects];
You can get the objects for the section like this.
[[myFetchedResultsController.sections objectAtIndex:<section>] objects];
** You have to replace with the number representing the section.
Hope this helps.

I'd recommend taking a look at the documentation for NSFetchedResultsController. It has example code for implementing the methods of UITableViewDataSource (including the ones that say how many sections the table has, and how many rows in each section), as well as documenting the property fetchedObjects, which you could use to see how many raw results you fetched.
[myFetchedResultsController.fetchedObjects count];

tableView.numberOfRows(inSection:) returns numbers of row in section, this method may not trigger fetched results controller's core data query.
let numberOfItems = (0..<tableView.numberOfSections).reduce(into: 0) { partialResult, sectionIndex in
partialResult += tableView.numberOfRows(inSection: sectionIndex)
}

Related

Lazy Loading in UITableview Sections IPhone

I have "n" Arrays with Images and I want to display images correspondingly in "n" sections of tableview using lazy loading concept.I know how to display one array images in table containing one section.Can anyone Help me???
Thanks in Advance
You pretty much do the same thing; but rather than return the number if images as rows in tableView:numberOfRowsInSection and return numberOfSectionsInTableView: as 1 - you turn things around. Have tableView:numberOfRowsInSection return 1 (so one section per image) and numberOfSectionsInTableView: return the number of images.
Your tableView:cellForRowAtIndexPath: code sees the same change; rather than take the index from indexPath.row you take it from indexPath.section.
And that is pretty much it.
Dw.
Just:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [yourImagesArray count];
}

Saving and loading state of tableview

I have a tableview where the user can make sections of people using a slider. So each section can have any number of people. I want to save the state of that tableview and then reload it when they come back.
I figured that since I'm using core data I can give each person a row and section attribute. So I'm able to save that but I don't know the best way to use those values to fill the tableview when it reappears.
I don't think that NSUserDefaults would work the best because I have many groups that can be broken into sections. I've been struggling with the best way to do this for a few days now and I'm still not sure what way to go.
More (per mihir mehta):
// Set core data values
int sec = 0;
int row = 0;
for (NSArray *section in groupsArray) {
for (People *person in section) {
[person setSubgroupSection:[NSNumber numberWithInt:sec]];
[person setSubgroupRow:[NSNumber numberWithInt:row]];
row++;
}
sec++;
row = 0; // new section so restart the row count
}
If you are already familiar with CoreData then perhaps you should stick with the plan you describe. The way I see it you should make some kind of TableViewInfoManagedObject:NSManagedObject. This TableViewInfoManagedObject should have members like #dynamic numberOfSections for example that describe what you need for your table view to work.
If you use CoreData to manage the people already consider using relationships to map numberOfSections to numberOfGroups or whatever you have in your People:NSManagedObject.
Also you need to consider when the appropriate time to "save" your state, which seems to be completely determined by the slider. In that case you may want to implement an IBAction for valueChanged.
EDIT 0: Based on the snippet you have provided it seems like at the end of the loop you would have the requisite info you need. The final value of sec should correspond to the UITableViewDataSource delegate method -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView and I am not really sure why you are setting the row number of the People object unless you are trying to achieve some sort order, which should be accomplished anyway by an NSSortDescriptor. So tableView:numberOfRowsInSection should return something like [[peopleinSection: section] count] and your tableView:cellForRowAtIndexPath should be set up so that it returns a cell like cell.textLabel.text = [[[peopleInSection:indexPath.section] objectAtIndex:indexPath.row] getPersonName]. Makes sense?
How about creating a class (subclass of NSObject) for each object that you need to save, and in that class you can add properties for each object. Then, you can use NSKeyedArchiver/Unarchiver to save and load your objects back to reuse.
Make a function that will take row and Section as argument and Returns that particular person by searching the array .... Got my point ?

Delete tableview section header view

I have a tableview with 3 sections / 3 customs section header view...
After I delete a row in one of this section and if the section come empty, how I can delete the section header view.
Thanks
One of the approaches could be to maintain flags as to whether the section has become empty and return zero height for that section's header and footer and then execute reloadSections:withRowAnimation: when the only row in section is deleted.
This is certainly better when you have section specific customizations which would become tricky to handle if we were to remove the section from our model. If there are no customizations as such, you could go about maintaining an array of arrays. Once the row array is emptied, you can discard the section from the sections array. This will reflect on reloadData.
In either case, you will need to affect the model to change the view.
what you can do after you delete the row is call the method -(void)reloadData. If you are already doing this, you need to update your datasource to indicate that the row has been deleted and in - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView you need to check that. Let me know if that helps!
One way I have dealt with this problem is implementing the section title like such:
-(NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return ([[allData objectForKey:[keys objectAtIndex:section]] count] > 0) ? [keys objectAtIndex:section]:#"";
}
This just checks that the array of objects for that section actually has something if it does it returns the name of the section if not it returns an empty string which hides the header title.
The table view does need to be updated for the change to come into effect, also I was a dictionary full of arrays and an array full of the dictionary keys. but something similar could be easily implemented. This method allows for insertion back into that section without having to re-instantiate an array.
Hope it helps.

iPhone UITableView - Visible Cells

I have a grouped UITableView, with cells in section 2 depending on cells in section 1. More precisely, each cell in section 1 is associated with multiple cells of section two and deleting a row in section 1 needs to delete the associated rows in section 2.
I have my dataSources all set up and everything works fine if all cells are visible. However, if the cells from section 2 haven't been loaded in the UITableView yet, I have a problem because the data source is updated for section 2 too.
I'm looking at this method visibleCells in UITableView. But I'm using custom UITableView cells and get an unrecognized selector exception if I try to access one of the labels in a cell.
How do I get around this?
Thanks,
Teja.
I believe what you were looking for is:
if ([tableView visibleCells] containsObject: theCellOfInterest]) {
// Do whatever you want to do.
}
Sorry if I wasn't clear the first time (or maybe even the second time too), but here's an answer to a repost of the same question.
Deleting multiple (not yet loaded) rows in UITableView

Best (Any) way blend tableview section header onto top of a grouped tableview

I'd like to add section headers to my grouped table view's sections but I'd like them to appear seamless (see image). The default, as we're all well aware of, is rounded top corners on the first row of a grouped table view cell so it ends up looking like crap when you merge them.
Any way to specify when indexPath.row = 0 that the UITableViewCell should use row style "middle" or something like that?
If not then what are my options? I guess I could scratch the section header and use Row 0 as a quasi-header then push my array data +1 to fill the rest of the table? I'd rather not roll my own from scratch...if possible.
Sample Table http://img35.imageshack.us/img35/8181/sampletable.png
Edit:
"Crap" looks like this:
alt text http://img25.imageshack.us/img25/9748/crapsection.png
Don't do what you're doing, it's against HIG
Ok, ok, I'll tell you how to do it:
You're going to want to do your own cell background views. The default grouped one is not what you want.
When a tableview asks you for a cell, set its backgroundView and selectedBackgroundView to something that looks appropriate for its place in the tableview.
Usually, this means a UIImageView with the appropriate image, though you can go wild here with a custom view, but there are gotchas.
So in your case, you would do
if (indexPath.row > sectionRowCount - 1) {
//Not the last row
//Put in the middle background
} else {
//Put in the end background
}
Then you'll want a custom table section header, but that's pretty easy.
In your case, you probably won't have to worry about when there's just one row, so that makes things even easier.
Take a look at the tutorial here:
cocoa with love basically what you need is 3 different images. One for the top row, one for the bottom, and a 3rd for the middle rows.
You could also not use the section header, but instead use a custom cell as the first cell of the section. So when ([indexPath row] == 0), return a custom cell that is the "header" and then return the "regular" cells (offset by one row) for the rest. You'll also have to make adjustments to the numberOfRowsInSection function to return +1.