Search code examples
iosobjective-cuser-interfacerefreshredraw

iOS GUI refresh


I am using setNeedsDisplay on my GUI, but there update is sometimes not done. I am using UIPageControllView, each page has UIScrollView with UIView inside.

I have the following pipeline:

1) application comes from background - called applicationWillEnterForeground

2) start data download from server

2.1) after data download is finished, trigger selector

3) use dispatch_async with dispatch_get_main_queue() to fill labels, images etc. with new data

3.1) call setNeedsDisplay on view (also tried on scroll view and page controller)

Problem is, that step 3.1 is called, but changes apper only from time to time. If I swap pages, the refresh is done and I can see new data (so download works correctly). But without manual page turn, there is no update.

Any help ?

Edit: code from step 3 and 3.1 (removed _needRefresh variables pointed in comments)

 -(void)FillData {
    dispatch_async(dispatch_get_main_queue(), ^{

    NSString *stateID = [DataManager  ConvertStateToStringFromID:_activeCity.actual_weather.state];

    if ([_activeCity.actual_weather.is_night boolValue] == YES)
    {
          self.contentBgImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"bg_%@_noc", [_bgs objectForKey:stateID]]];

        if (_isNight == NO)
        {
            _bgTransparencyInited = NO;
        }

        _isNight = YES;

    }
    else
    {
        self.contentBgImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"bg_%@", [_bgs objectForKey:stateID]]];

        if (_isNight == YES)
        {
            _bgTransparencyInited = NO;
        }

        _isNight = NO;

    }
    [self.contentBgImage setNeedsDisplay]; //refresh background image

    [self CreateBackgroundTransparency]; //create transparent background if colors changed - only from time to time


    self.contentView.parentController = self;
    [self.contentView FillData]; //Fill UIView with data - set labels texts to new ones

    //_needRefresh is set to YES after application comes from background

    [self.contentView setNeedsDisplay]; //This do nothing ?

    [_grad display]; //refresh gradient

}); 
}

And here is selector called after data download (in MainViewController)

-(void)FinishDownload:(NSNotification *)notification
{
    dispatch_async(dispatch_get_main_queue(), ^{

        [_activeViewController FillData]; //call method shown before

        //try call some more refresh - also useless
        [self.pageControl setNeedsDisplay];

         //[self reloadInputViews];
         [self.view setNeedsDisplay];


    });

} 

In AppDelegate I have this for application comes from background:

-(void)applicationWillEnterForeground:(UIApplication *)application
{
    MainViewController *main = (MainViewController *)[(SWRevealViewController *)self.window.rootViewController frontViewController];


    [main UpdateData];
} 

In MainViewController

-(void)UpdateData
{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(FinishForecastDownload:) name:@"FinishDownload" object:nil]; //create selector

    [[DataManager SharedManager] DownloadForecastDataWithAfterSelector:@"FinishDownload"]; //trigger download
}

Solution

  • None of proposed solutions worked. So at the end, I have simply remove currently showed screen from UIPageControllView and add this screen again. Something like changing the page there and back again programatically.

    Its a bit slower, but works fine.