views:

1510

answers:

9

The standard Grouped UITableView style allows UITableViewCells to be drawn with rounded corners at the top and bottom of each section. How is this accomplished? How does the cell know its own location within its section, and how does it know when to change its rounded edges?

I want to make my own rounded cells, and I have images to use, but don't know when to show which image

Note: I already know how the UITableView works, and I know how to use it. I just thought that since a UITableView is able to automatically draw rounded corners at the correct places, I should be able to as well, without needing to add anything to my data source or delegate.

A: 

The cells dont know where they go...The table view has cells, You are the one telling the table view WHAT goes in the cell. You do this in the DataSource where you implement cellForRowAtIndexPath...The way this works :

An index path has a row and a section

For a grouped table view

A section pertains to a group, and a row pertains to 1 entry in that section, the way UITableView knows how many rows are in a section and how many sections there are is the DataSources methods numberOfSectionInTableView and the method numberOfRowsInSection, this will make the right calls to cellForRowAtIndexPath, it is up to you to recognize which section and row is being queried and you need to build your cell according to these specifications.

A good way to do this i s you can have a Dictionary with keys of section names and values of NSArray with the values that go in that section.

So you implementation for numberOfSectionsInRows would look like

return [[dictionary allKeys] count]

And the implmentation of numberOfRowsInSection would look like

NSString* key=[[dictionary allKeys] objectAtIndex:sectionNumber]
  return [[dictionary objectForKey:key] count]

You can always refer to the UITableView programming guide at http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/TableView_iPhone/Introduction/Introduction.html Hope that helps

Daniel
That's not a particularly helpful answer. I already know how the UITableView works, and I know how to use it. I just thought that since a UITableView is able to automatically draw rounded corners at the correct places, I should be able to as well, without needing to add anything to my data source or delegate.
Ed Marty
Allcells have rounded corners...
Daniel
The UITableView isnt drawning rounded corners, the UITableCell is made to look like that inside its draw method...
Daniel
If you want to have you own custom cells subclass UITableViewCell and make your customization in there, your question was not particularly clear i guess, sorry for all the comments
Daniel
Yes, I know all that too. My question, very specifically, is that since I'm in UITableViewCell doing the customization, how do I know which rounded corners to draw?
Ed Marty
O i see, because you have different corners for different cells? Well what i can suggest i s passing in the indexPath to the cell and based on that it will know what to do. OR just create different subclasses of UITableViewCell and depending on the indexPath when u return them, make the appropriate one
Daniel
Yes, I'm using my own backgroundImages. I have one for a top cell, one for a middle cell, one for a bottom cell, and one for a single cell. See my comments on TahoeWolverine's answer as to why passing in indexPaths is exactly what I don't want to do.
Ed Marty
You are going to have to, magically having the table view what you want wont work...
Daniel
A: 

Simply add a property to your custom UITableViewCell (depending on implementation) class that contains an int, NSNumber, or an NSIndexPath specifying which one it is. In you're using a data structure instead, then put it in you element in that data structure. Then you simply set the property when you create the data structure, something like elt.id=i, and then you access it in the cellForRowAtIndexPath, something like if (elt.id == 0 || elt.id == n-1) where n is the number of rows in your section.

I might have totally missed your question, but if I did, just comment and I'll post again.

TahoeWolverine
Yeah, you kinda missed the question. I know how to statically tell the cell at creation time where it is. However, that doesn't tell it if it's at the bottom of its section without telling it what table it's in. Even then, the problem is the fact that it's static. If I delete the top row, I need to notify the second row to reset itself. I don't have to do this when using regular UITableViewCells.
Ed Marty
Well in that case, you can just call reloadData, and cellForRowAtIndex path should be called once each for your remaining cells, at which point you can turn the rectangle 2nd and 2nd to last cells into rounded ones.
TahoeWolverine
A: 

Unfortunately, I have found no solution to this problem, and have resorted to subclassing UITableViewController and UITableViewCell into a generic solution that I can extend as necessary.

Ed Marty
A: 

You don't do this in cell. Rounded corners are drawn in [tableView viewForHeaderInSection] and viewForFooterInSection.

The way I do it is to use Plain tableview style, then use these two views for roundness and cells are normal, no rounds.

Aleksandar Vacic
Could you elaborate on that? I don't quit understand how that would work out.
Ed Marty
In order to avoid the trickery of keeping up with what is 1st row and last row, I used section header and footer and draw rounded parts in there. This keeps the rows clean, with simple background image view. You basically need to carefully slice the design.It's not applicable if you need to render row selections (you'll have to change header or footer when edge rows are selected), so I use this simple technique for stuff where selection is not needed. The benefit is that it's really easy o implement, in default UITableViewController.
Aleksandar Vacic
+1  A: 

If you need more robust and general stuff, take a look at http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html - Matt Gallagher shows what you need, pretty effectively. He basically recreates UITableViewController from UIViewController, while adding ability to use your own custom graphics. I'm just working on applying this to one my projects, so far it looks it would do the job.

Aleksandar Vacic
A: 

Without getting into who draws what, you can know which cell is the last cell in its section inside of cellForRowAtIndexPath very easily.

You're passed in the indexPath of the cell you need to provide, right? You're also passed the tableView.

call [tableView numberofRowsInSection:indexPath.section] and if it's == ([indexPath.row]-1) you know you're being asked to supply the last cell in that section.

At the time that cellForRowAtIndexPath is being called, the cell is guaranteed to be at the indexPath passed in.

God of Biscuits
Yes, but cellForRowAtIndexPath isn't called when moving a row or deleting rows.
Ed Marty
A: 

You can use

- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell

for this issue. In my example I am using this to scroll the cell (with custom content) to the top of the view.

xna
except a UITableViewCell doesn't have a reference to its table.
Ed Marty
+3  A: 
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
int rows = [(UITableView *)self.superview numberOfRowsInSection:indexPath.section];

if (indexPath.row == 0 && rows == 1) {
// the one and only cell in the section
}
else if (indexPath.row == 0) {
//top
}
else if (indexPath.row != rows - 1) {
//middle
}
else {
//bottom
}
Darren Inksetter
That's half the answer, but how does it automatically change its rounded corners as cells are moved around?
Ed Marty
+2  A: 

There is sectionLocation method of UITableViewCell that returns integer telling you what you need:

  • 1 - middle cell
  • 2 - top cell
  • 3 - bottom cell
  • 4 - single cell

This method works, but it's not documented, which makes it much less useful.

aleh