How to Reload Text Inside UITableCell using AFNetworking

白昼怎懂夜的黑 提交于 2019-12-12 05:15:49

问题


I'm fetching the value of my UILabel from Rotten Tomatoes API and I want my text inside my custom cell to update whenever the value has been fetched already. I tried doing that by reloading my UITableView but it goes on a loop.

Here's my code:

if (ratingTomatoLabel.text == nil)
    {
        NSLog(@"   Nil");

        NSString *stringWithNoSpaces = [movieTitle.text stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
        NSString *rottenTomatoRatingString = [NSString stringWithFormat:@"%@%@%@", @"http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=6844abgw34rfjukyyvzbzggz&q=", stringWithNoSpaces, @"&page_limit=1"];
        NSLog(@"   Rotten URL: %@", rottenTomatoRatingString);
        NSURL *rottenUrl = [[NSURL alloc] initWithString:rottenTomatoRatingString];
        NSURLRequest *rottenRequest = [[NSURLRequest alloc] initWithURL:rottenUrl];

        AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:rottenRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
            NSLog(@"      3");
            self.testDict = [JSON objectForKey:@"movies"];
        } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
            NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
        }];

        [operation start];

        NSLog(@"   %@", ratingTomatoLabel.text);
        ratingTomatoLabel.text = @"...";
    }
    else if ([ratingTomatoLabel.text isEqualToString:@""])
    {
        NSLog(@"   isEqualToString");
        // Do nothing
    }
    else
    {
        NSLog(@"   else");
    }

    return tableCell;

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"      fetched!");

    if ([ratingTomatoLabel.text isEqualToString:@"..."])
    {
        NSLog(@"      2nd nil");
        NSDictionary *dict = [self.testDict valueForKey:@"ratings"];
        self.criticsScoreString = [NSString stringWithFormat:@"%@", [dict valueForKey:@"critics_score"]];
        self.criticsScoreString = [self.criticsScoreString stringByReplacingOccurrencesOfString:@" " withString:@""];
        self.criticsScoreString = [self.criticsScoreString stringByReplacingOccurrencesOfString:@"(" withString:@""];
        self.criticsScoreString = [self.criticsScoreString stringByReplacingOccurrencesOfString:@")" withString:@""];
        self.criticsScoreString = [NSString stringWithFormat:@"%@%@", self.criticsScoreString, @"%"];

        ratingTomatoLabel.text = self.criticsScoreString;
        NSLog(@"      %@", ratingTomatoLabel.text);
    }
    else
    {
        NSLog(@"      2nd not nil");
        NSLog(@"      %@", ratingTomatoLabel.text);
        // Do nothing
    }
}

If I added the code [self.myTableView reloadData]; after setting the value in my text, it goes on a loop. What's the best way to do this? Thanks!

UPDATE: Included updated code and another method. Also, my ratingTomatoLabel always goes nil when it's not displayed.


回答1:


You should use KVO (Key-value observing) to detect when there are changes to your dictionary or array - in this case it seems self.testDict.

When you receive this notification, use UITableView's -visibleCells method to update only the visible cells - the others will obviously take on their new value when their cell is recycled using -tableView:cellForRowAtIndexPath:.

What's required for KVO: Registering/deregistering when views load/change and setting the variable you wish to observe...

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if([keyPath isEqual:@"testDict"])
    {
        NSLog(@"KVO change: %@", change);
        NSArray *visibleCells = [self.myTableView visibleCells];
        for(UITableViewCell *cell in visibleCells)
        {
            if(/*cell matches the one I'm targeting OR just update regardless*/)
                // assign value to UILabel
        }
    }
}

// Call this from -viewDidLoad
- (void)registerAsObserver
{
    [self addObserver:self forKeyPath:@"testDict" options:NSKeyValueObservingOptionNew context:NULL];
}

// Call this from -viewWillDisappear and -viewDidUnload (may not be necessary for -viewDidUnload if already implemented in -viewWillDisappear)
- (void)unregisterAsObserver
{
    [self removeObserver:self forKeyPath:@"testDict"];
}

Lastly, to update the cell(s) that have changed, call the -reloadRowsAtIndexPaths:withRowAnimation: method to have the underlying system refresh the cell.




回答2:


Jaytrix

With the AFNetworking calls happening asynchronously, consider using some sort of notification to tell the main thread (UI) when work is complete or an error occurs.

Frank



来源:https://stackoverflow.com/questions/14703985/how-to-reload-text-inside-uitablecell-using-afnetworking

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!