3

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

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

谢谢!

4

3 回答 3

4

我的猜测是系统实际上并没有启动删除打开面板的动画,直到运行循环的后期,startProcess:返回之后。因此,如果您的“<code>此处调用其他一些方法”需要很长时间才能运行,那么动画开始之前将需要很长时间。

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

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

- (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
    });
}
于 2012-11-13T05:20:25.930 回答
1

在后台线程上进行缓慢工作的建议很好。

但是要尽快关闭面板,只需[openDialog close]在从-openVideoFile.

于 2012-11-13T05:37:24.157 回答
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];   
}
于 2014-06-25T16:18:02.430 回答