我在GUI上使用setNeedsDisplay,但有时候没有更新。我使用的是UIPageControllView
,每个页面都有UIScrollView
,内有UIView
。
我有以下管道:
1)应用程序来自后台 - 名为applicationWillEnterForeground
2)从服务器开始下载数据
2.1)数据下载完成后,触发选择器
3)使用dispatch_async
与dispatch_get_main_queue()
一起使用新数据填充标签,图片等
3.1)在视图上调用setNeedsDisplay
(也尝试滚动视图和页面控制器)
问题是,调用了步骤3.1,但只是不时地改变apper。如果我交换页面,刷新完成,我可以看到新数据(所以下载工作正常)。但是没有手动翻页,就没有更新。
任何帮助?
编辑:来自步骤3和3.1的代码(删除了注释中指向的_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];
}
在MainViewController中
-(void)UpdateData
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(FinishForecastDownload:) name:@"FinishDownload" object:nil]; //create selector
[[DataManager SharedManager] DownloadForecastDataWithAfterSelector:@"FinishDownload"]; //trigger download
}
答案 0 :(得分:1)
试试这个:
[self.view performSelectorOnMainThread:@selector(setNeedsLayout) withObject:nil waitUntilDone:NO];
或查看此链接:
http://blackpixel.com/blog/2013/11/performselectoronmainthread-vs-dispatch-async.html
答案 1 :(得分:0)
setNeedsDisplay
触发drawRect:
并用于“重绘视图”,而不是配置视图或其子视图。
您可以覆盖drawRect:
并修改标签等,但这不是它的用途,setNeedsLayout
/ layoutSubviews
也不是。
您应该创建自己的updateUI
方法,在其中使用新数据更新UI,而不依赖于专门用于重绘像素(setNeedsDisplay
)或调整子视图框架的系统调用({{ 1}})。
您应该在drawRect:
方法中设置所有label.text
,imageView.image
等。另外,最好只尝试通过此方法设置这些值,而不是直接从任何方法设置。
答案 2 :(得分:0)
所提议的解决方案均无效。所以最后,我只是从UIPageControllView
删除当前显示的屏幕并再次添加此屏幕。有点像改变页面然后再以编程方式返回。
它有点慢,但工作正常。