UITableView won't update properly (even when reloadData is called)

I'm building an iPhone app that has a portion of the interface that looks exactly like the Most Popular section of the YouTube iPhone app.

This "popular" section is accessible from the tab bar at the bottom, and the navigation bar at the top contains a UISegmentedControl to select "Today, this week, month, etc."

Since most of the application consists of UITableViews with cells containing very similar structured content, I created a generic MyAppTableViewController that inherits from UITableViewController . My popular section "consists of PopularTableViewController , which inherits from MyAppTableViewController . The actual UITableView is inside MyAppTableViewController.

The PopularTableViewController function has a method:

- (void) segmentChangeTimeframe:(id)sender {
    UISegmentedControl *segCtl = sender;
    if( [segCtl selectedSegmentIndex] == 0 )
    {
        // Call [self parse-xml-method-which-resides-in-MyAppTableViewController]
    }
    //... ... ...
}

      

MyAppTableViewController uses NSXMLParser and therefore has the code:

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    [self.myTableView reloadData];
}

      

(There are other methods that update the data structure from which the table view gets data)

I have put the console output code in the xml parsing methods, and on startup, selecting different segments, need to parse the correct XML files correctly and the data structure seems to contain the correct values.

The problem is that the contents of the table cells will not change! ! UNLESS! ... Cell scrolls out of sight and then back into view ... THEN changed!

I have searched for this issue many times and one suggestion for a similar problem was to put [self.myTableView reloadData] in its own method for example. myReloadDataMethod and then use:

[self performSelectorOnMainThread:@selector(myReloadDataMethod) withObject:nil waitUntilDone:NO];

      

I tried to put the above code in the parserDidEndDocument method and it made no difference! I am absolutely stumped and I am wondering if anyone knows what is going on here.

Update:

The code for filling the cells is done with

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *MyIdentifier = @"MyIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier] autorelease];
    }

    // Set up the cell
    int itemIndex = [indexPath indexAtPosition: [indexPath length] - 1];
    NSString *artistName = [[myItemList objectAtIndex: itemIndex] objectForKey: @"itemA"];
    NSString *mixName = [[myItemList objectAtIndex: itemIndex] objectForKey: @"itemB"];
    cell.textLabel.text = itemA;
    cell.detailTextLabel.text = itemB;
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

    return cell;
}

      

The above code is in MyAppTableViewController , which is also myItemList.

+2


source to share


4 answers


Your code -performSelectorOnMainThread:

is for making changes to model classes on a background thread. UI events (including -reloadData

) must occur on the main thread. If you are not using a background thread, then this is optional. If you are, then something like this is a must.

If you change the value of a particular cell, then how you achieve this is changing the cell itself. On iPhone, cells are full view (unlike Mac), so if you want to change your data, you just change your data and call -setNeedsDisplay

. You can get the cell (view) for a given location with -cellForRowAtIndexPath:

. You can determine if a given cell is on the screen with -indexPathsForVisibleRows

or -visibleCells

.



Very rarely needs to be called -reloadData

. You should only do this if you are throwing everything away and loading completely different data. Instead, you should use insert / delete routines to add / remove rows, and you just need to update the views of existing rows when their data changes.

+5


source


I had this same problem and it was because I had a call to [tableView beginUpdates] without calling endUpdates after.



+1


source


Have you tried [tableView setNeedsDisplay:YES]

?

0


source


After calling -reloadData, you get a callback on tableView: numberOfRowsInSection :? I'm pretty sure self.myTableView isn't here:

    - (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.myTableView reloadData];

      

}

-1


source







All Articles