我有一个基于文档的应用程序,可以进行适度强烈的保存(大约10-15秒,但非常明显)。为了让最终用户不要认为应用程序已挂断,我添加了一个进度指示器,该指示器在文档上显示为工作表。我可以在保存文档时将进度指示器显示为工作表,并且在保存结束时工作表正确消失。但是,指标显示为灰色。我知道这更像是一个美学问题,但我会赞赏如何解决这个问题。
以下是进度指示器的屏幕截图。它不是蓝色和动画条,而是灰色的,仍然是灰色的。
我在下面列出了相关代码。
代码显示进度指示器:
- (void) showProgressIndicatorSheet
{
NSStoryboard *storyboard = [NSStoryboard storyboardWithName:@"Main" bundle:nil];
modalProgressWindowController = [storyboard instantiateControllerWithIdentifier:@"modalProgressWindowController"];
NSArray *windowControllers = self.windowControllers;
if ([windowControllers count] > 0) {
NSWindowController *controller = windowControllers[0];
[controller.window beginSheet:modalProgressWindowController.window completionHandler:nil];
}
}
隐藏表单的代码:
- (void) hideProgressIndicatorSheet
{
if (modalProgressWindowController) {
NSArray *windowControllers = self.windowControllers;
if ([windowControllers count] > 0) {
NSWindowController *controller = windowControllers[0];
[controller.window endSheet:modalProgressWindowController.window];
}
}
}
显示指示符的代码然后在保存时隐藏它:
- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError {
[self showProgressIndicatorSheet];
/* code to save data to file */
[self hideProgressIndicatorSheet];
}
正如评论中提到的那样,可能使用窗口表是这里的问题。我做了一些搜索,发现beginModalSessionForWindow
和它的documentation。看起来很有希望,所以我尝试使用它,但有进度条灰色的相同问题。我也有一个新问题,尽管我打电话给[NSApp stopModal]
但我无法停止模态。
代码显示进度指示器:
- (void) showProgressIndicatorSheet
{
NSStoryboard *storyboard = [NSStoryboard storyboardWithName:@"Main" bundle:nil];
modalProgressWindowController = [storyboard instantiateControllerWithIdentifier:@"modalProgressWindowController"];
session = [NSApp beginModalSessionForWindow:modalProgressWindowController.window];
}
解雇模式的代码:
- (void) hideProgressIndicatorSheet
{
[NSApp endModalSession:session];
}
显示指示符的代码然后在保存时将其解除:
- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError {
[self showProgressIndicatorSheet];
BOOL response = NO;
BOOL beganSave = NO;
while ([NSApp runModalSession:session] == NSModalResponseContinue) {
if (!beganSave) {
beganSave = YES;
response = [self saveToDBForURL:url];
}
}
[self hideProgressIndicatorSheet];
return response;
}
saveToDBForURL中的stopModal:
- (BOOL)saveTODBForURL: (NSURL *) url {
/* save method */
// stop modal after saving is done
[NSApp stopModal];
// return whether save was success or not...
return response;
}
解决了! Willeke关于调用注释中的所有方法是正确的。但仅凭这一点还不够......我仍然得到了灰色的进度条。我偶然发现了关于SO "Document sheet not responding to keyboard events"的以下帖子。事实证明,你必须在IB中启用“标题栏”!
在IB中启用了标题栏,这里有更新的代码(希望没有其他人需要遇到这种怪异!):
代码显示表
- (void) showProgressIndicatorSheet
{
NSArray *windowControllers = self.windowControllers;
if ([windowControllers count] > 0) {
NSWindowController *controller = windowControllers[0];
((BWProgressIndicatorSheetViewController *)modalProgressWindowController.window.contentViewController).progressLabel.stringValue = @"Saving workspace...";
[controller.window beginSheet:modalProgressWindowController.window completionHandler:nil];
session = [NSApp beginModalSessionForWindow:modalProgressWindowController.window];
}
}
解雇表的代码
- (void) hideProgressIndicatorSheet
{
[NSApp endModalSession:session];
if (modalProgressWindowController) {
NSArray *windowControllers = self.windowControllers;
if ([windowControllers count] > 0) {
NSWindowController *controller = windowControllers[0];
[controller.window endSheet:modalProgressWindowController.window];
}
}
}
显示指示符的代码然后在保存时将其解除
- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError {
[self showProgressIndicatorSheet];
BOOL response = NO;
BOOL beganSave = NO;
while ([NSApp runModalSession:session] == NSModalResponseContinue) {
if (!beganSave) {
beganSave = YES;
response = [self saveToDBForURL:url];
}
}
[self hideProgressIndicatorSheet];
return response;
}
最后... saveToDBForURL中的stopModal:
- (BOOL) saveToDBForURL: (NSURL *) url
{
// do saving here
[NSApp stopModal];
return response;
}