Xcode table view reload continually adds data to the table - xcode

I have an rss parser as part of my app code, and it is working fine and loading the rss xml file and populating the tableview fine.
The problem is with a refresh/reload button, which does reload the rss data, but it APPENDS the new data to the table and the table just grows and grows in size.
What the behaviour should do is to clear the old table data and rebuild the table with the new data - so that the table always shows just ONE set of data and doesn't keep growing every time the reload/refresh is pressed.
The table build code is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
cell.textLabel.text = [[stories objectAtIndex: storyIndex] objectForKey: #"date"];
cell.detailTextLabel.text = [[stories objectAtIndex: storyIndex] objectForKey: #"title"];
[cell.textLabel setLineBreakMode:UILineBreakModeWordWrap];
[cell.textLabel setNumberOfLines:0];
[cell.textLabel sizeToFit];
[cell.detailTextLabel setLineBreakMode:UILineBreakModeWordWrap];
[cell.detailTextLabel setNumberOfLines:0];
[cell.detailTextLabel sizeToFit];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
And the reload/refresh button code is:
- (void)reloadRss {
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
[[self navigationItem] setLeftBarButtonItem:barButton];
[barButton release];
[activityIndicator release];
[activityIndicator startAnimating];
[self performSelector:#selector(parseXMLFileAtURL) withObject:nil afterDelay:0];
[newsTable reloadData];
}
I have tried to solve this by adding the line:
if (stories) { [stories removeAllObjects]; }
to the reload section, which I think should work and does clear the table, but the app then crashes the app with an EXC_BAD_ACCESS.
Any ideas or suggestions greatly appreciated!

Actually, have now solved this!
Was due to "autoreleasing" elements of the array, so after clearing this out, they were invalid.
Removing autorelease and just releasing these objects in the final dealloc worked.

The Code EXC_BAD_ACCESS does mean, that you want connect at a variable that does not exists anymore.
In your code example, I can see, the problem to see at the following two lines of code:
[activityIndicator release];
[activityIndicator startAnimating];
You release the activityIdicator befor starting the Animating.
Try to release at the end of the function.
[activityIndicator startAnimating];
[self performSelector:#selector(parseXMLFileAtURL) withObject:nil afterDelay:0];
[newsTable reloadData];
[activityIndicator release];

Related

Switched from tableview to colelctionview now didselectitematindexpath not called

So I switched from a UITableView to a UICollectionView. The cells are all loading just fine and look beautiful, but now I can no longer select any of them. The taps are recognized in the logs, but it doesn't take me to the view that it's supposed to take me to anymore.
The only things that changed really are the ones the ones you see commented out in the "cellForItem" section. Everything else is identical to how it was when it was working in the TableView. It's just supposed to take me to the ViewController specified when you tap. Instead the tap is recorded, but it does nothing. Any help would be appreciated.
Also I tried getting rid of the [collectionView deselectItemAtIndexPath:indexPath animated:YES];
...but it didn't make any difference.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
PlaceCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
//UINib * placeCell = [UINib nibWithNibName:#"Shops" bundle:nil];
// NSArray *topLevelItems = [placeCell instantiateWithOwner:self options:nil];
// cell = [topLevelItems objectAtIndex:0];
Place *p = [_entries objectAtIndex:indexPath.row];
cell.placeName.text = p.PName;
NSLog(#"p:%#",p.PName);
cell.placeName.textColor = [UIColor colorWithRed:3/255.0f green:6/255.0f blue:4/255.0f alpha:1.0f];
NSString *pIcon;
pIcon = typeName;
//NSLog(pIcon);
cell.placeImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:p.PImage]]];
NSLog(#"i:%#",p.PImage);
return cell;
}
-(void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"Tap Recognized");
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
Place *p = [_entries objectAtIndex:indexPath.row];
DetailPlaceViewController * pvc = [[DetailPlaceViewController alloc] init];
[pvc setPlace:p];
[self.navigationController pushViewController:pvc animated:YES];
}
Well this one was fun...
For some odd reason my navigation controller isn't working... so of course using the navigation controller to load a view wasn't going to work. Simple enough solution... load the view without the navigation controller. I was just going to delete this question, but maybe somebody might be in a similar situation one day:
[self presentViewController:pvc animated:YES completion:nil];

How to push new view from TableViewCell?

In my app I am trying to navigate to a new View from a TableViewCell, But i dont know how. Could you help guys? I am using Xcode 4.6. and .xib, no storyboard. I am very new to coding so please explain it as simple as possible! Here is what i have tried, please correct me:
- (void)viewDidLoad
{
tableData = [[NSArray alloc] initWithObjects:#"aaoversikt1", #"Paul", #"George", #"Ringo", nil];
[super viewDidLoad];
UILabel *nav_title1 = [[UILabel alloc] initWithFrame:CGRectMake(60, 10, 220, 25)];
nav_title1.font = [UIFont fontWithName:#"Arial-BoldMT" size:18];
nav_title1.textColor = [UIColor whiteColor];
nav_title1.adjustsFontSizeToFitWidth = NO;
nav_title1.textAlignment = NSTextAlignmentCenter;
nav_title1.text = #"Ă…lesund";
nav_title1.backgroundColor = [UIColor clearColor];
self.navigationItem.titleView = nav_title1;
}
#pragma mark - TableView Data Source methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section;
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - TableView Delegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AAOversiktViewController *aaoversikt1 = [[AAOversiktViewController alloc] initWithNibName:#"AAOversiktViewController" bundle:nil];
[self.navigationController pushViewController:aaoversikt1 animated:YES];
}
Thank You!
From first glance I would say that the problem lies within your [self.navigationController pushViewController] method. Have you initiated a navigation controller in your app either in the app delegate or root view controller?
If not i would recommend:
[self presentViewController:aaoversik1 animated:YES completion:NULL];
If you are wanting to push through the navigation stack so that you have a back button then I would look at implementing a UINaviationController.
Otherwise you can create a custom back button and use the same method in this post to present the root view controller (not totally recomended as using UINavigationController is much cleaner).
Let me know if this has been of any help, T

Showing Activity indicator while loading sqlite local database

I have a local SQLite Database and need to return a large number of records. It takes a several seconds to load so I want to add an activity indicator. The activity indicator seems to be running as it should but the problem is the pool isn't allowing the arrays to return any value see below.
- (void)viewDidLoad
{
[super viewDidLoad];
activityIndicator = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
activityIndicator.frame = CGRectMake(0.0, 0.0, 48.0, 48.0);
activityIndicator.center = self.view.center;
[self.view addSubview:activityIndicator];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[activityIndicator startAnimating];
[self performSelectorInBackground:#selector(loadData) withObject:nil];
}
//What I need to load from SQLITE
-(void)loadData {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Path to the database
//CODED HERE FOR DATABASE TO OPEN AND QUERY HERE TO BUILD ARRAYS
NSString *firstField = [NSString stringWithUTF8String:cFirst];
NSString *secondField = [NSString stringWithUTF8String:cSecond];
NSString *thirdField = [NSString stringWithUTF8String:cThird];
[FirstArray addObject:firstField];
[SecondArray addObject:secondField];
[ThirdArray addObject:thirdField];
//Checking to see if records are being added to the arrays
NSString *recordAdded = [NSString stringWithFormat:#"%# - %# - %#", firstField, secondField, thirdField];
NSLog(#"Song: %#", recordAdded);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[activityIndicator stopAnimating];
[pool release];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
NSString *firstValue = [firstArray objectAtIndex:indexPath.row];
NSString *secondValue = [secondArray objectAtIndex:indexPath.row];
NSString *thirdValue = [thirdArray objectAtIndex:indexPath.row];
NSString *details = [NSString stringWithFormat:#"%# - %#", secondValue, thirdValue];
cell.textLabel.text = cellValue;
cell.detailTextLabel.text = details ;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
When I'm looking at the debugger I see that the arrays are being built as the activity indicator is going. The problem is that I think the pool release is releasing my arrays too.
The code returns the query in the table view fine when I don't add the Pool and activity indicator.
Can anyone help to point me in the right direction to not release the arrays if that's what is happening here? Any kind of help would be much appreciated. :-)
---Also---
After looking around more I found that I have to pass the arrays back to the main thread. This is what I gather from searching online.
[self performSelectorOnMainThread:#selector(done:) withObject:cellData waitUntilDone:NO];
How would I go about loading the table with these arrays?
Not sure about your pool releasing the array, your code seems pretty direct. You may want to check whether you are really getting any data from your database.
However, I notice that you stop animating the activity indicator in the background thread. UI activity should be done in the main thread. I just did this coding last night and solved my problem using this thread. Put your stop animating code in the selector specified by performSelectorOnMainThread.
The strings are fine because they are being added to the array.
It looks like your array is being released, but you don't show the code for it.
How are you creating the array itself? If it is autoreleased, it will be deallocated when you drain the pool. You should "retain" it instead of "auotrelease"ing it.
Try to add [tableview reloadData] at the end of the -(void)loadData method

My tableview crash when i scroll

I don't undestand... i succeed in populate my table view but when i scroll it crash without message..
i create my tabQuestion with a NSMutablearray and then add this in my delegate : cellForRowAtIndexPath
NSDictionary *question = [self.tabQuestion objectAtIndex:indexPath.row];
[cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];
cell.textLabel.text = [NSString stringWithFormat:#"%#", [question objectForKey:#"question"]];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [question objectForKey:#"reponse"]];
if ([[question objectForKey:#"bOk"] isEqualToString:#"1"]) {
cell.imageView.image = [UIImage imageNamed:#"ok.png"];
}
else
{
cell.imageView.image = [UIImage imageNamed:#"ok.png"];
}
[question release];
return cell;
You shouldn't release objects that were returned by method objectAtIndex: of NSArray. It happens very rare.
Try to remove first of all line: [question release];
Then check if your self.tabQuestion contains needful amount of objects.

SDWebImage and UITableViewCell

I'm working with SDWebImage and UITableView
- (UITableViewCell *)tableView:(UITableView *)the_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *MyIdentifier = [NSString stringWithFormat:#"MyIdentifier"];
NSDictionary *info = [tableData objectAtIndex:indexPath.row];
UITableViewCell *cell = [the_tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier] autorelease];
if(!addImage) [addImage release];
addImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"placeholder.png"]];
[addImage setFrame:CGRectMake(7, 10, 50, 50)];
[cell setIndentationLevel:6];
[cell.contentView addSubview:addImage];
}
if(info != NULL) {
cell.textLabel.text = [info objectForKey:#"title"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Version: %#",[info objectForKey:#"version"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSString *imageURL = [NSString stringWithFormat:#"%#",[info objectForKey:#"imageURL"]];
[addImage setImageWithURL:[NSURL URLWithString:imageURL] placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
}
return cell;
}
Which Works Great for the first 6 Results (The amount that can fit on the immediate view)
But as I scroll down the list, it seems like it's just re-using images from the first 6 cells, and on some cells images change depending on their location on the screen.
Also, if I call reloadData, the images from the previous UITableCells stay on screen!
Am I doing something wrong here? I've followed the example code on github..
Thanks!
(Answered by the OP in a question edit. Moved here as a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
OK, So I found the problem.
For anyone else out there with the Same issue, this is where you're doing it wrong!
Notice how I'm adding the Image into SubView while creating a cell:
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier] autorelease];
addImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"placeholder.png"]];
[addImage setFrame:CGRectMake(7, 10, 50, 50)];
[cell.contentView addSubview:addImage];
Well, what SDWebImage was trying to do is constantly update that addImage variable, which wasn't a property of my cell class.
So, what I did to fix this problem is create my own UITableViewCell subclass, that init's with a ImageView and I get SDWebImage to setImage on that property!
I hope this helps someone!

Resources