Objective c 如何关闭NSOpenPanel或为什么它不关闭';你不能自动关闭吗?

Objective c 如何关闭NSOpenPanel或为什么它不关闭';你不能自动关闭吗?,objective-c,macos,cocoa,nsopenpanel,Objective C,Macos,Cocoa,Nsopenpanel,我很难理解如何关闭NSOpenPanel。它确实会自动关闭,但所需的时间比我希望的要长 这是我的密码: - (IBAction)startProcess:(id)sender { NSString *path = [Document openVideoFile]; // open file // some other method calls here } // NSOpenPanel for file picking +(NSString*) openVideoFile {

我很难理解如何关闭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方法的末尾

如果有人知道如何立即关闭面板,在用户选择文件后单击OK按钮,我将非常感谢任何帮助


谢谢大家!

我的猜测是,在
startProcess:
返回之后,直到运行循环的稍后部分,系统才真正启动移除打开面板的动画。因此,如果您的“
此处的某些其他方法调用
”需要很长时间才能运行,那么动画开始之前将需要很长时间

理想的解决方案是在后台队列上执行缓慢的“其他方法调用”,因为您应该尽量避免阻塞主线程。但是,这可能需要您使各种事情线程安全,而目前不是,这可能是困难的

另一种不同的方法是将它们推迟到运行循环的后面:

- (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
    });
}

在后台线程上执行缓慢工作的建议是好的


但要更快地关闭面板,只需在从
-openVideoFile
返回之前调用
[openDialog close]
,另一个解决方案是在继续之前给运行循环一些时间来处理事件,例如使用
[[nsrunlop currentlunloop]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];   
}

close方法没有关闭面板,我试过了…它只是使它不活动…嗯。当我重新阅读您的代码时,我看到所有这些都是在
-runModal
返回后发生的。我不知道为什么此时面板仍在屏幕上–我认为单击“确定”并退出运行模式会导致面板从显示中删除。Rob实际上得到了答案…请阅读他所说的,这就是问题所在:)