UITableView placeholder for dequeued cells - iphone

There's this stupid little thing thats annoying me and i'd love to hear your opinion about it.
I'm using a UITableView with custom UITableViewCell's to display some news item from an RSS feed. this is working great ,
the only problem is - when is scroll down, i see the "old" cells, and only when my scroll stops, it loads the new content.
So my question is - can i somehow put a placeholder so it would at least show "loading" when scrolling or some other kind of indication?
Thanks in advance :)
Shai

When do you fill you cells with content, normally you do this in the UITableViewDataSource
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
This will get called every time a cell is needed before displaying it. If you set the data form that cell here is will be update before it gets displayed.
If you are grabbing something from the web, which could take some time, this is the place to set any content that you grab from the web to loading or placeholder images.
Then in the UITableViewDelegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
Start the async fetching of data and update the cell when the data is received.

To avoid duplication of previous data in new cell, use an unique CellIdentifier.
NSString *CellIdentifier = [NSString stringWithFormat:#"%i", indexPath.row];
NewsCell *cell = (NewsCell *) [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (cell == nil)
{
cell = [[ActivitiesCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:CellIdentifier];
}
In NewsCell.m file, use following code and load the new cell by calling initWithStyle method, instead of using loadNibNamed.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
// Initialization code.
}
return self;
}

Related

Tableview inside Flipview using Utility template

I'm new to iOS dev, so I do apologise for asking potentially dumb question.
What I want to do is something very similar to the default Weather app; where the app has a info button, it flips to another view which has a table along with a Done button to go back to the app.
I'm using the 'Utility Application' template which does most of this for me :)
However, I am now struggling to add a tableview into the flipview. Am I on the right path? I'm using storyboard at the moment - beginning to realise this is most likely a limitation on the GUI (after all a GUI can only go so far). If so, is this possible programatically and how would I go about applying it on a default 'Utility Application' template.
I'm using Xcode 4.2.
Any help would be appreciated. Thanks in advance :)
First of all, you'll want to drag and drop a UITableView onto your flipsideViewController in interface builder. Make sure that you like its delegate and data source to the view controller.
Then change flipsideViewController.h to create an instance variable for the array that will store the text for the cells labels and for the controller to conform to the tables delegate and data source methods.
#interface FlipsideViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
NSArray *myArrayOfItems;
}
In flipsideViewController.m alloc/init and populate your array in viewDidLoad
myArrayOfItems = [[NSArray alloc] initWithObjects:#"firstItem",#"secondItem",#"thirdItem",#"fourthItem", nil];
And finally, copy and paste the following and you should have a working table!
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myArrayOfItems count];
}
- (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];
}
cell.textLabel.text = [myArrayOfItems objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Selected cell index:%i",indexPath.row);
}

How to access the cell in tableview?

I am new to the iPhone development. I got stuck with a problem. I want a check box function implemented in my UITableView. But my UITableViewCells are custom cell which consist of image and 3 UILabels. I could bring a sub view to the table view so that check box image can placed and I am successful in that. But the problem comes is whenever I click on the image only the last cell check box get changed. I would like to access the cell which I've clicked.
I have tried this
UITableViewCell *cell = [self cellForRowAtIndexPath:indexPath]
But this crashes since cell is custom.
Can any one suggest me a good method to do that?
Instead of using
UITableViewCell *cell = [self cellForRowAtIndexPath:indexPath]
try using
YourCustomCell *cell = (YourCustomCell *)[self.tableView cellForRowAtIndexPath:indexPath];
Hope it helps
First of all you need to define a tag -
#pragma imageViewTag 1
then in your cellForRowAtIndexPath assign this tag to your image view
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
then you can access your image view any where with the help of this tag as -
UITableViewCell *cellView = (UITableViewCell*) [tblView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
UIImageView *imgView = (UIImageView*) [cellView viewWithTag:imageViewTag];
In your TableView DidSelect Delegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIImageView *image = [cell.contentView viewWithTag:15];
//You should have set the tag value as 15 when creating the image in cell
//and you should have added to the cell contentview
}
If you cant able to get the cell then probably you wouldnt have used the reusable cell concept correctly. So post your entire cellforrowindex code.
If you are using the check kind of thing. Why dont you use the default disclosure indicator of tableview instead of your image.

UITableViewDelegate methods

Here is an xcode project that I just did to ask this question:
http://www.mediafire.com/?z26ufsfhby62br9
Open the log and run it. You will find that it outputs display: x and create: x where x is a number 0 to 49 and corresponds to the cell of the same number. It should only output to 22 before any scrolling is performed as Apple are always boasting that their tableviews are loaded as needed.
It basically shows that tableView:willDisplayCell:forRowAtIndexPath: and tableView:cellForRowAtIndexPath: are fired for each cell pretty much as soon as the tableview appears, why is this?
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"create: %i", indexPath.row);
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:#"%i", indexPath.row];
return cell;
}
- (void) tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"display: %i", indexPath.row);
}
Why are the above meothds called just after the tableView loads (and just before each cell appears)? Surely they should be called just before each cell appears only?
These are the default delegate methods.. This will be be called for each cell everytime.
You use willDisplayCell:forRowAtIndexPath: to configure things like font and text color. In the newer version of the iPhone, with certain table configurations, if you configure things like the label text color in the tableView:cellForRowAtIndexPath: method, your changes will be lost at some point before the cell is actually displayed. Here you can do things like change the label's color, adjust background highlighting, such things as these.
If your table view is reloading before it actually fully displays, that could cause the behavior you're seeing. Then the cells would get initialized, prepared for display, but then all of that would be lost (before even shown on screen) as the table is reloaded.

iPhone Sdk: UITableViewCells copy themselves randomly

i have been trying to figure this out but i just can't....
for some reason, everytime my UITableView reaches a certain length due to the number of rows and sections, cells seem to randomly copy themselves into different cells at the end of the table without me wanting or programming it... Anyone else have this issue or knows how it's resolved? Any help is appreciated! Tanks.
Edit:
The "row" property is a counter which gets counted up to 13 and is then reset to 0 and counted up again and i always want the string "newUpdate" to be displayed in the corresponding row but at the same time i don't want the rest of the cells to be blank i want them to keep their old content until they're overwritten because the counter is starting at 0 again.
#import "ServerUpdateViewController.h"
#implementation ServerUpdateViewController
#synthesize newUpdate;
#synthesize row;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 15;
}
- (NSString *)tableView: (UITableView *)table titleForHeaderInSection:(NSInteger) section {
return #"All Updates to Server";
}
// 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];
}
if (indexPath.row == self.row) {
cell.textLabel.text = self.newUpdate;
}
// Set up the cell...
return cell;
}
- (void)dealloc {
[super dealloc];
}
#end
You're re-using cells. In your cellForRowAtIndexPath: method, you need to fully configure the cell every time it's called.
There are a few things that can cause this and I can't be specific without seeing code, but it comes down to the fact that cells are reused. The entire content of the cell will have to be re-set/redrawn every time cellForRowAtIndexPath is called.

Checkbox cell in a table view: User can't check it

I need help in using checkbox cell. I currently added the object to tableview. It looks ok until i tried building and running the program where I cannot check the checkbox. I am currently using a tableview which displays items runtime with a checkbox for each item so i can have multiple selections.
I am new to xcode and I have been stuck for a week with this problem. i tried google but still no luck.
Any snippets, answers, or explanations is very much appreciated.
First we need to edit this method: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath. Assuming you generated a Navigation-based application, this method should already be there, only commented out. I don't know the exact details of your implementation, but you somehow have to keep track of the checkbox state for each cell in the tableView. For example, if you had a BOOL array, the following code would work:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (checkboxArray[indexPath.row])
checkboxArray[indexPath.row] = NO;
else
checkboxArray[indexPath.row] = YES;
[self.tableView reloadData];
}
Now that we know what cells need to have a checkmark next to them, the next step is to modify how the cell is displayed. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath handles the drawing of each cell. Building off the previous example, this is how you would display the checkbox:
- (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];
}
if (checkboxArray[indexPath.row]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
cell.accessoryType = UITableViewCellAccessoryNone;
// Configure the cell.
return cell;
}
If we don't call reloadData, the checkmark will not show up until it goes off-screen and reappears. You need to explicitly set the accessoryType each time because of the way cells are reused. If you set the style only when a cell is checked, other cells that may not necessarily be checked will have a checkmark when you go to scroll. Hopefully this gives you a general idea on how to use checkmarks.