iOS GUI 刷新

Posted

技术标签:

【中文标题】iOS GUI 刷新【英文标题】:iOS GUI refresh 【发布时间】:2014-08-28 00:24:40 【问题描述】:

我在我的 GUI 上使用 setNeedsDisplay,但有时没有完成更新。我使用的是UIPageControllView,每个页面都有UIScrollView,里面有UIView

我有以下管道:

1) 应用来自后台 - 称为applicationWillEnterForeground

2) 开始从服务器下载数据

2.1) 数据下载完成后,触发选择器

3) 使用dispatch_asyncdispatch_get_main_queue() 用新数据填充标签、图像等

3.1) 在视图上调用 setNeedsDisplay(也尝试在滚动视图和页面控制器上)

问题是,步骤 3.1 被调用,但只是不时发生变化。如果我交换页面,则刷新完成,我可以看到新数据(因此下载正常)。但是没有手动翻页,就没有更新。

有什么帮助吗?

编辑:步骤 3 和 3.1 中的代码(删除了 cmets 中指向的 _needRefresh 变量)

 -(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

); 

这是数据下载后调用的选择器(在 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];


    );

 

在 AppDelegate 中,我有这个来自后台的应用程序:

-(void)applicationWillEnterForeground:(UIApplication *)application

    MainViewController *main = (MainViewController *)[(SWRevealViewController *)self.window.rootViewController frontViewController];


    [main UpdateData];
 

在主视图控制器中

-(void)UpdateData


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

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

【问题讨论】:

你在 dispatch_async 块中调用 setNeedsDisplay 吗?如果是这种情况:需要在主线程上调用 setNeedsDisplay! @SebastianBorggrewe 我用 dispatch_get_main_queue() 在 dispatch_async 中给他打电话 能把dispatch块的代码贴出来吗? @SebastianBorggrewe 添加了代码片段 好的,只是为了澄清。您已确保 [self.contentView setNeedsDisplay];和 [self.pageControl setNeedsDisplay];实际上被称为(断点或 NSLog)并且两者(如果您使用故事板和/或 nib 文件)都是链接的出口 【参考方案1】:

setNeedsDisplay 触发drawRect: 并用于“重绘视图的像素”,而不是配置视图或其子视图。

您可以覆盖 drawRect: 并在那里修改您的标签等,但这不是它的用途,setNeedsLayout/layoutSubviews 也不是。

您应该创建自己的 updateUI 方法,在该方法中使用新数据来更新 UI,而不是依赖专门用于重绘像素 (setNeedsDisplay) 或调整子视图框架 (drawRect:) 的系统调用。


您应该在updateUI 方法中设置所有label.textimageView.image 等。此外,最好尝试仅通过此方法而不是直接通过任何方法设置这些值。

【讨论】:

我应该在自己的 updateUI 中添加什么?我已经自己更改了所有标签,但唯一缺少的是那些新值是可见的。我仍然看到旧的。【参考方案2】:

试试这个:

[self.view performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO];

或查看此链接:

http://blackpixel.com/blog/2013/11/performselectoronmainthread-vs-dispatch-async.html

【讨论】:

【参考方案3】:

建议的解决方案均无效。所以最后,我只是从UIPageControllView 中删除了当前显示的屏幕并再次添加此屏幕。类似于以编程方式更改页面并再次返回。

它有点慢,但工作正常。

【讨论】:

以上是关于iOS GUI 刷新的主要内容,如果未能解决你的问题,请参考以下文章

如何使 pyqt gui 刷新

Python GUI 以固定速率刷新

使用 AutoIt 刷新 GUI

带有 pyqtgraph 的 GUI 从不刷新

在 GUI 文本区域上添加和刷新文本?

如何在 Java 中刷新 GUI?