【发布时间】:2014-08-28 00:24:40
【问题描述】:
我在我的 GUI 上使用 setNeedsDisplay,但有时没有完成更新。我使用的是UIPageControllView,每个页面都有UIScrollView,里面有UIView。
我有以下管道:
1) 应用来自后台 - 称为applicationWillEnterForeground
2) 开始从服务器下载数据
2.1) 数据下载完成后,触发选择器
3) 使用dispatch_async 和dispatch_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 文件)都是链接的出口
标签: ios objective-c user-interface refresh redraw