在 NSDocument 上显示进度指示器 sheet 显示为灰色(尽管仍然有用)
Displaying a progress indicator sheet on NSDocument shows up greyed out (though still serves purpose)
第一次尝试 - beginSheet: completionHandler: Method
我有一个基于文档的应用程序,它会进行适度密集的保存(大约 10-15 秒,但绝对引人注目)。为了让最终用户不认为应用程序已挂起,我在文档上添加了一个显示为 sheet 的进度指示器。在保存文档时,我可以将我的进度指示器显示为 sheet,并且在保存结束时 sheet 会正确消失。但是,该指示器是灰色的。我知道这更像是一个美学问题,但希望能提供有关如何解决此问题的指示。
下面是进度条的截图。它不是蓝色的动画条,而是灰色且静止的。
我在下面列出了相关代码。
显示进度指示器的代码:
- (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];
}
}
隐藏代码sheet:
- (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: 方法
正如评论所暗示的那样,可能使用 window sheet 是这里的问题。我四处搜索了一下,发现 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" 上偶然发现了以下 post。事实证明,您必须在 IB 中启用“标题栏”!
在 IB 中启用标题栏后,这里是更新后的有效代码(希望没有其他人需要 运行 进入这种怪异状态!):
要显示的代码 sheet
- (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];
}
}
关闭代码sheet
- (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;
}
第一次尝试 - beginSheet: completionHandler: Method
我有一个基于文档的应用程序,它会进行适度密集的保存(大约 10-15 秒,但绝对引人注目)。为了让最终用户不认为应用程序已挂起,我在文档上添加了一个显示为 sheet 的进度指示器。在保存文档时,我可以将我的进度指示器显示为 sheet,并且在保存结束时 sheet 会正确消失。但是,该指示器是灰色的。我知道这更像是一个美学问题,但希望能提供有关如何解决此问题的指示。
下面是进度条的截图。它不是蓝色的动画条,而是灰色且静止的。
我在下面列出了相关代码。
显示进度指示器的代码:
- (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];
}
}
隐藏代码sheet:
- (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: 方法
正如评论所暗示的那样,可能使用 window sheet 是这里的问题。我四处搜索了一下,发现 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" 上偶然发现了以下 post。事实证明,您必须在 IB 中启用“标题栏”!
在 IB 中启用标题栏后,这里是更新后的有效代码(希望没有其他人需要 运行 进入这种怪异状态!):
要显示的代码 sheet
- (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];
}
}
关闭代码sheet
- (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;
}