objective-c – 如何在Cocoa中显示和管理简单的应用程序模式对话框

objective-c – 如何在Cocoa中显示和管理简单的应用程序模式对话框,第1张

概述我不确定我是以正确的方式做事,还是我把它全部搞砸了. 我有一个非常简单的测试应用程序(不是基于文档的)我创建的用于学习如何在Cocoa应用程序中使用应用程序模式对话框. 使用应用程序项目“TestModalDialog”,我有一个简单的MainMenu.xib,默认视图和一个按钮,“Show Dialog”,我补充说.我创建了第二个名为TheDialog.xib的XIB,它有“取消”和“确定”按钮 我不确定我是以正确的方式做事,还是我把它全部搞砸了.

我有一个非常简单的测试应用程序(不是基于文档的)我创建的用于学习如何在Cocoa应用程序中使用应用程序模式对话框.

使用应用程序项目“TestModalDialog”,我有一个简单的MainMenu.xib,默认视图和一个按钮,“Show Dialog”,我补充说.我创建了第二个名为TheDialog.xib的XIB,它有“取消”和“确定”按钮.该xib拥有一个派生自NSWindowController的类,名为“TheDialogController”;窗口和代表连接到控制器.

在主视图上选择“显示对话框”将启动对话框.选择“取消”或“确定”将关闭对话框.这是非常简单的代码:

//  TestModalDialogAppDelegate.h  //  TestModalDialog  #import <Cocoa/Cocoa.h>  @class TheDialogController;  @interface TestModalDialogAppDelegate : NSObject <NSApplicationDelegate>  {    NSWindow *window;    TheDialogController* theDialogController;  }  @property (assign) IBOutlet NSWindow *window;  - (IBAction)showDialog:(ID)sender;  @end  //  TestModalDialogAppDelegate.m  //  TestModalDialog  #import "TestModalDialogAppDelegate.h"  #import "TheDialogController.h"  @implementation TestModalDialogAppDelegate  @synthesize window;  - (voID)applicationDIDFinishLaunching:(NSNotification *)aNotification  {    theDialogController= [[TheDialogController alloc] init];  }  - (voID)dealloc  {  if(nil != theDialogController)       [theDialogController release];    [super dealloc];  }  - (IBAction)showDialog:(ID)sender  {    if(nil == theDialogController)    {      NSAlert* alert= [NSAlert alertWithMessageText:@"Dialog Error" defaultbutton:nil alternatebutton:nil otherbutton:nil informativeTextWithFormat:@"The dialog controller was not allocated."];      [alert runModal];      return;    }  NSInteger result= [NSApp runModalForWindow:[theDialogController window]];   // Do something with result.... }  @end  //  TheDialogController.h  //  TestModalDialog  #import <Cocoa/Cocoa.h>  @interface TheDialogController : NSWindowController  {    // BOol userClickedCloSEOrOk; // Removed based on answer.    // Should declare a common define - just being lazy.    NSInteger userClickedOk;  // Added based on answer.    UInt16 timesShown;   }  - (IBAction)showWindow:(ID)sender;  - (IBAction)closeDialog:(ID)sender;  - (IBAction)okDialog:(ID)sender;  //- (BOol)windowshouldClose:(ID)sender;   // Removed based on answer.  - (voID)windowWillClose:(NSNotification*)notification;  // Added based on answer.   - (voID)windowDIDBecomeKey:(NSNotification*)notification;  // To set Title when modal.  @end  //  TheDialogController.m  //  TestModalDialog  #import "TheDialogController.h"  @implementation TheDialogController  - (ID)init  {    self = [super initWithWindowNibname:@"TheDialog"];    userClickedOk= 0;  // Added based on answer.    // userClickedCloSEOrOk= FALSE;  // Removed based on answer.    return self;  }  -(voID)dealloc  {    // Do member cleanup if needed.  [super dealloc];  }  - (voID)windowDIDLoad  {    [super windowDIDLoad];    // Initialize as needed....    [[self window] center];  // Center the window.  }  // Does not show with runModalForWindow.  - (IBAction)showWindow:(ID)sender  {    // Just playing with the window Title....    ++timesShown;    Nsstring* newTitle= [Nsstring stringWithFormat:@"Shown %d Times",timesShown];    [[self window] setTitle:newTitle];    return [super showWindow:sender];  }  // This method no longer used for this solution based on the answer.  //- (BOol)windowshouldClose:(ID)sender  //{  //  if(!userClickedCloSEOrOk)  // The user dID not click one of our buttons.  //    [NSApp abortModal];  //  else  //    userClickedCloSEOrOk= FALSE;  // Clear for next time.  //  //  return TRUE;  //}  // Added based on answer.  - (voID)windowWillClose:(NSNotification*)notification  {    [NSApp stopModalWithCode:userClickedOk];    userClickedOk= 0;  // reset for next time.  }  // Note - the Title will update every time the window becomes key. To do the  // update only once per modal session,a flag can be added. There might be a better  // notification to catch.  - (voID)windowDIDBecomeKey:(NSNotification*)notification  {    ++timesShown;    Nsstring* newTitle= [Nsstring stringWithFormat:@"Shown %d Times",timesShown];    [[self window] setTitle:newTitle];  }  - (IBAction)closeDialog:(ID)sender  {    //userClickedCloSEOrOk= TRUE;  // Removed based on answer.    //[NSApp abortModal];  // Removed based on answer.    //[[self window] performClose:self];  // Removed based on answer.    [[self window] close];  // KNow we want to close - based on answer.  }  - (IBAction)okDialog:(ID)sender  {    userClickedOk= 1;  // Added based on answer.    //userClickedCloSEOrOk= TRUE;  // Removed based on answer.    //[NSApp stopModal];  // Removed based on answer.    //[[self window] performClose:self];  // Removed based on answer.    [[self window] close];  // KNow we want to close - based on answer.  }    @end

我遇到了这种模式的问题 – 在我输入userClickedCloSEOrOk并测试之前,如果用户点击关闭按钮(左上角的红点),对话框将关闭,但模态会话仍在运行.

我意识到我可以把关闭按钮从对话框开始,但是在那里,我已经展示了一个很好的方法来捕捉那个场景,还是有更好的方法?或者,我开始做错了什么,这给我带来了问题?

任何意见,将不胜感激.

注 – 原始示例中的代码已注释掉,并根据答案替换为代码.还添加了新的通知处理程序.

解决方法 在okDialog:和closeDialog:方法中调用close而不是performClose:以避免窗口调用windowshouldClose:delegate方法.这样你就不需要userClickedCloSEOrOk了.

另外我认为你想要调用stopModalWithCode:而不是stopModal,因为在app委托中你似乎对结果感兴趣.你可以调用stopModal或stopModalWithCode:而不是abortModal,因为你在调用它时总是在runloop中(当你在模态runloop之外时,就像在另一个线程或计时器的runloop中一样).

在windowshouldClose中:你正在做一个动作(abortModal),你应该只回答“如果这个窗口关闭”的问题. windowWillClose:delegate方法是您应该在需要时执行 *** 作的地方.

当有一个窗口时,表格很有用,它告诉用户他们不能对它做任何事情,直到他们完成表格中的任何内容.当您有多个用户无法与之交互的窗口时,应用程序模式窗口非常有用,直到它们完成模态窗口中的任何内容或者存在涉及整个应用程序但不依赖于一个窗口内容的错误.在他们的HIG Apple中建议尽可能避免使用Application-modal窗口.

总结

以上是内存溢出为你收集整理的objective-c – 如何在Cocoa中显示和管理简单的应用程序模式对话框全部内容,希望文章能够帮你解决objective-c – 如何在Cocoa中显示和管理简单的应用程序模式对话框所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1015218.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存