我有以下问题: 我希望用户在按下按钮时下载。在此下载过程中,我想隐藏其他按钮(这将打开下载的文件,因此我想确保在更新尚未完成时没有人尝试打开文件)。 在此过程中是否可以隐藏这些按钮?
所以到目前为止我尝试和体验过的是:
我尝试了以下(Pseudocode):
-(void)updatingprogress
{
buttona.hidden=TRUE;
}
-(void)updatingfinished
{
buttona.hidden=FALSE;
}
updateFiles()
{
[self updatingprogress]
... make downloads...
[self updatingfinished]
}
因此,通过日志记录,我看到,我在我想要的时刻进入我的功能,但是在“updatedprogress”期间没有完成按钮的更改。任何想法如何解决这个问题? 谢谢和最好的问候!
答案 0 :(得分:4)
一个常见问题是您正在尝试更新后台线程上的UI元素。如果您的updateFiles
方法在另一个主题上发生,则您的按钮可能无法正确隐藏。要将方法分派给主线程,您可以使用NSOperationQueue
API或GCD
API。
NSOperationQueue:
[[NSOperationQueue mainQueue] addBlockOperation:^ {
buttona.hidden = YES;
}];
GCD:
dispatch_async(dispatch_get_main_queue(), ^ {
buttona.hidden = YES;
});
这两个API都做同样的事情。我通常会尝试使用highest abstraction possible,所以在这种情况下我会使用NSOperationQueue
方法
答案 1 :(得分:1)
另一种可能性是你在主线程上做了所有工作,但是没有考虑到这样一个事实,即通常UIKit更改在你下载到runloop之后才会生效。
背景逻辑是您不希望部分更改可见,例如如果你写的:
// okay, set to success
label.textColor = [UIColor greenColor]; // was previously red
label.text = @"Success"; // previously said 'Failure'
您明确不想要的是“失败”一词以绿色显示,然后将该词改为“成功”。您希望两个更改以原子方式发生。 Apple通过将UIKit更新一起批处理并在任何预定方法之外实现它们来实现这一目标。
因此,如果您在主线程上有一个函数执行一些UI更改,那么有些工作然后撤消UI更改,但是所有这些都没有退出到runloop,那么更改将永远不会被看到。
最快的解决方案是:
- (void)updateFiles
{
[self updatingProgress];
[self performSelector:@selector(doFileUpdate) withObject:nil afterDelay:0.0];
// what does the above achieve? It schedules doFileUpdate on the runloop, to
// occur as soon as possible, but doesn't branch into it now. So when this
// method returns UIKit will update your display
}
- (void)doFileUpdate
{
/* heavy lifting here */
[self updatingFinished];
}