我很难理解如何关闭NSOpenPanel。 会自动关闭,但需要的时间比我想要的要长。
这是我的代码:
- (IBAction)startProcess:(id)sender
{
NSString *path = [Document openVideoFile]; // open file
// some other method calls here
}
// NSOpenPanel for file picking
+(NSString*) openVideoFile
{
NSOpenPanel *openDialog = [NSOpenPanel openPanel];
//set array of the file types
NSArray *fileTypesArray = [[NSArray alloc] arrayWithObjects:@"mp4", nil];
[openDialog setCanChooseFiles:YES];
[openDialog setAllowedFileTypes:fileTypesArray];
[openDialog setAllowsMultipleSelection:FALSE];
if ([openDialog runModal] == NSFileHandlingPanelOKButton)
{
NSArray *files = [openDialog URLs];
return [[files objectAtIndex:0] path];
}
else
{
return @"cancelled";
}
return nil; // shouldn't be reached
}
有趣的是,如果用户点击“取消”,面板立即关闭,但如果用户从列表中选择一个文件,面板将保持打开状态,直到程序到达startProcess方法的末尾。
如果有人知道如何立即关闭面板,用户在选择文件后单击“确定”按钮后,我将非常感谢您的帮助!
谢谢!
答案 0 :(得分:3)
我的猜测是,在startProcess:
返回后,系统实际上并没有启动删除打开面板的动画,直到运行循环的后期。因此,如果您的“some other method calls here
”需要很长时间才能运行,那么动画开始前需要很长时间。
理想的解决方案是在后台队列上执行慢速“其他方法调用”,因为您应该尽量避免阻塞主线程。但是,这可能需要你制作各种线程安全的东西,这些东西目前都不是,这可能很难。
另一种方法就是推迟在运行循环中执行它们:
- (IBAction)startProcess:(id)sender {
NSString *path = [Document openVideoFile]; // open file
dispatch_async(dispatch_get_main_queue(), ^{
// some other method calls here
});
}
或者您可能需要将其延长一段时间:
- (IBAction)startProcess:(id)sender {
NSString *path = [Document openVideoFile]; // open file
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 100), dispatch_get_main_queue(), ^(void){
// some other method calls here
});
}
答案 1 :(得分:1)
在后台线程上做慢工作的建议很好。
但要更快关闭面板,只需在从[openDialog close]
返回之前调用-openVideoFile
。
答案 2 :(得分:0)
另一个解决方案是给runloop一些时间来处理事件,然后再继续使用例如[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
...像
if ([openDialog runModal] == NSFileHandlingPanelOKButton)
{
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
NSArray *files = [openDialog URLs];
return [[files objectAtIndex:0] path];
}