This is the code for cellForRowAtIndexPath: method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil) { cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [array objectAtIndex:row];
return cell;
}
When i use [self.tableView reloadData]; nothing happening?
You need to implement at least the tableView:numberOfRowsInSection: method as part of the UITableViewDataSource protocol, and tableView:cellForRowAtIndexPath: (which you already did). You should also implement numberOfSectionsInTableView:.
Then you need to make sure that your class is actually used as a data source:
self.tableView.dataSource = self;
That needs to be either done via Interface Builder or in awakeFromNib or some other method like viewDidLoad:.
Do you check your dataSource and delegate of UITableView ? I think the dataSource is nil or something else.
Try putting a break point in cell for row and see if it is called when u call reloadData. Also pls check if the changes are already made to array from which the cells are populated and make sure the table view is connected to its datasource and delegate.
Related
just created an UITableView,
trying to display some custom data from an array, but what ever I do, i get no text displayed.
NSLog tell me the right text and right amout but no text in table cell.
here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"test";
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
Things to check:
Is cellForRowAtIndexPath getting called? Put a breakpoint in
Make an array in ViewDidLoad (property, alloc'd) and addObjects #"One", #"Two", #"Three", nil and then cell.textLabel.text = [theArray objectAtIndex:indexPath.row];
IfcellForRow is being called, this will show in the cells.
What doesConfigureCell do? Include the code please.
Also check your tableView delegate methods are being called (NumberofRowsInSection etc)
Always set cell properties (text, images, accessory views, etc) in the
tableView:willDisplayCell:forRowAtIndexPath
delegate method.
UITableView sometimes send a prepareForReuse to the cell after it is returned from
tableView:cellForRowAtIndexPath
which causes the cell to reset it's labels and images.
I am using ios5 storyboards with a UITableViewController with a UITableViewCell subclass. I do not want to design the visual elements of the cell in the storyboard designer for the view, because I want to use a reusable subclass of UITableViewCell (specifically TDBadgedCell).
I have set my cell identifier in the storyboard designer, and all of the rows load correctly in the UITableView as long as I'm not setting any of the properties unique to TDBadgedCell. If I set the badgeString property though which is unique to TDBadgedCell, I get an exception. I narrowed down that dequeueReusableCellWithIdentifier: is not returning a cell of type TDBadgedCell.
I'm only running into this with a UITableViewController. I have a UIViewController with an embedded UITableView set up in the same fashion and it's not an issue. Any ideas?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *CellIdentifier = #"PhoneNumberCell";
TDBadgedCell *cell = (TDBadgedCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([cell isKindOfClass:[TDBadgedCell class]])
{
NSLog(#"It is TDBadgedCell");
}
else
NSLog(#"It is NOT TDBadgedCell");
I had a similar issue in that I am subclassing UITableViewCell but not using storyboard. Here is my solution to using different cell classes dependent on if the user had purchase the unlock feature of the app. Hope it helps someone.
In a nutshell, I had the cell with several objects including a UITextView object. I wanted to lock down the copy and paste feature of the UITextView object in the lite version but then release the feature once the user had purchased in in-app product.
I had two UITableViewCell classes, one with UITextView as it is and another with UITextView subclassed with canBecomeFirstresponder returning NO. That way the user could still scroll up and down the UITextview data but not copy and paste the data.
Here is the code and all I had to do was rename the reuse identifiers.
WHY? Because [self.tableview reloadData] would not rebuild the cells with the new class as the cell was still in existence. New cells off the screen would get the new class but existing ones would not. This solution rebuilds all cells once off after the purchase unlocking the added feature.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (your test if in-app was purchased is yes)
{
static NSString *MyIdentifier = #"MyCell";
FrontCell *cell = (FrontCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[FrontCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.shouldIndentWhileEditing = NO;
}
//....///
cell.trackDetails.text = [yourObject objectAtIndex:indexPath.row];
cell.trackDetails.delegate = self;
cell.trackDetails.tag = indexPath.row;
return cell;
}
else // inapp not purchased
{
static NSString *MyLockedIdentifier = #"MyLockedCell";
FrontCellLocked *cell = (FrontCellLocked *)[tableView dequeueReusableCellWithIdentifier:MyLockedIdentifier];
if (cell == nil)
{
cell = [[FrontCellLocked alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyLockedIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.shouldIndentWhileEditing = NO;
}
//....///
cell.trackDetails.text = [yourObject objectAtIndex:indexPath.row];
cell.trackDetails.delegate = self;
cell.trackDetails.tag = indexPath.row;
return cell; }
}
In storyboard,you can set the Custom Class property for a subclass of UITablviewCell.
Then dequeueReusableCellWithIdentifier method will return cell with the type of your subclass.
I think you are using wrong method for dequeuing the cells.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [self.tblProfileInfo dequeueReusableCellWithIdentifier:#"PostCell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
You forgot for indexPath at the end.
I've been trying to fill a UITableView with data from a NSMutableArray. I have a View-Based application project and so far I've tried every tutorial I found but so far, it just doesn't work. I linked the dataSource and delegate to the File's Owner, I added the procotols UITableViewDelegate and UITableViewDataSource to my UIViewController, I create an array containing 3 strings just to try and debug, everytime I load the app, the table stays empty.
I'm not sure what could be my error, or where I should look to find the problem, if you guys got any idea that would be nice.
Thank you
-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection: (NSInteger)section
{
return [yourArray count];
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [yourArray objectAtIndex:row];
return cell;
}
That should populate the table from an array. I've used it several times in my app.
I guess you did forget to call -reloadData on the table view.
Make sure the dataSource and delegate are properly connected to the view controller, also make sure your UITableView is property connected with the outlet if you are using storyboards or a xib file.
If nothing works I recommend you to use XLData that makes UITableView data loading much more simple to implement.
I have been trying to figure out how to set the accessoryType to UITableViewCellAccessoryCheckmark when the cell is selected but am having trouble finding a decent example of this.
If you know how to do this or a good tutorial could you please let me know that would be great.
To restrict the user to just one selection, meaning to create an exclusive list of one choice only, you could follow these steps;
Firstly, have a global index path declared in your .h file to keep track of the already selected cell ->
NSIndexPath *oldIndexPath;
When you create the cells, be sure to set the accessory type to none, so that no cell is selected by default when the table is seen;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CallIdentifier"];
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Finally, in the didSelectRowAtIndexPath delegate method, add the following code which will remove the checkmark from the already selected cell, and add a checkmark to the newly selected one.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (oldIndexPath==nil) { // No selection made yet
oldIndexPath=indexPath;
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else {
UITableViewCell *formerSelectedcell = [tableView cellForRowAtIndexPath:oldIndexPath]; // finding the already selected cell
[formerSelectedcell setAccessoryType:UITableViewCellAccessoryNone];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark]; // 'select' the new cell
oldIndexPath=indexPath;
}
}
Hope this works out! :)
Something like this may work:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:myTableView cellForRowAtIndexPath:indexPath];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
To answer the comment below, just push a viewController in the same method like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:myTableView cellForRowAtIndexPath:indexPath];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
// Then push a new view
iPhoneCustomViewController *myVC = [[iPhoneCustomViewController alloc] initWithNibName:#"iPhoneCustomViewController" bundle:nil];
[self.navigationController pushViewController:myVC animated:YES];
[myVC release];
// And deselect the row (if desired)
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Did you know that:
1.) UITableView keeps track of the index paths for the rows that have been selected? It's in an array called indexPathsForSelectedRows
2.) UITableView has a flag you can set to make it either single or multiple selection. You can change it by calling the setter setAllowsMultipleSelection:(BOOL).
So, assuming that the table has been set to single selection, we can do the following in the tableView:CellForRowAtIndexPath method ...
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[[cell textLabel] setText:#"Some Text"];
NSArray *selectedIndexPaths = [tableView indexPathsForSelectedRows];
if ([selectedIndexPaths containsObject:indexPath]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}else{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
return cell;}
This implementation of CellForRowAtIndexPath will give you a clean checkmark with no gray background when a cell is selected. You will need to set the checkmark in the didSelectRowAtIndexPath delegate method to make sure a cell gets the checkmark the moment it gets selected.
No need to create separate ivars or anything else to keep track of what was or wasn't selected. It's all neatly contained in the UITableView as Apple intended.
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType=UITableViewCellAccessoryCheckmark;
Implement this in didSelectRowAtIndexPath delegate method
From the docs:
The delegate handles selections in this method. One of the things it
can do is exclusively assign the check-mark image
(UITableViewCellAccessoryCheckmark) to one row in a section
(radio-list style). This method isn’t called when the editing property
of the table is set to YES (that is, the table view is in editing
mode). See "Managing Selections" in Table View Programming Guide for
iOS for further information (and code examples) related to this
method.
Here is an example:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]
cell.UITableViewAccessoryType = UITableViewCellAccessoryCheckmark;
}
I just have a basic (noob) question about cellForRowAtIndexPath get called?
I'm working through example code and I don't see it explicitly called anywhere?
Does any component of type UITableViewComponent automatically call this function when it is created?
Thanks
When a UITableView is displaying this method gets called per row. In it you will customize each cell with particular data for display.
Here's the class reference.
Here's a sample:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"FriendCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
Item *i = [itemArray objectAtIndex:row];
cell.textLabel.text = [i name];
cell.detailTextLabel.text = [i brewery];
[i release];
return cell;
}
This is called for each cell when the corresponding UITableView gets drawn. An index path is passed in, and based on the section and cell numbers, your code should generate a UITableViewCell to be displayed in the UI.
You can look here for a quick tutorial into how UITableViews work.