在創建Cocoa應用程序的時候,有時候我們需要在應用程序退出前讓用戶確認是否真正退出。這個可以用多種方法來實現。但是如果利用AlertSheet的話可以盡量使得過程更舒服。如下圖。
我們可以利用xcode里面已經為你創建好的Application的代理類來調用NSBeginAlertSheer來做做代理處理請求。接下來我們來看看具體的做法。
在Interface Builder里面從Application按下Control拉一條線到已經有的代理類上面,連接delegate的outlet。如下圖:

然后轉向代理類的代碼中加入如下代碼:
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
NSString *msg = @"Should this applicaion quit?";
SEL sel = @selector(sheetClosed:returnCode:contextInfo:);
NSBeginAlertSheet(@"Close",
@"OK",
@"Cancel",
nil,
window,
self,
sel,
NULL,
sender,
msg,
nil);
return NSTerminateLater;
}
- (void)sheetClosed:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
if (returnCode == NSAlertDefaultReturn)
{
[(NSApplication *)contextInfo replyToApplicationShouldTerminate:YES];
}
else
{
[(NSApplication *)contextInfo replyToApplicationShouldTerminate:NO];
}
}
其中:
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
是Application類得到是否退出消息的控制函數。其返回值為:NSTerminateNow
, NSTerminateCancel
和NSTerminateLater
。前兩個顧名思義,就是立刻退出和取消推出。最后一個則被用來使用回調/選擇函數處理后再用replyToApplicationShouldTerminate
來決定程序是否退出。
下面就是如何用NSBeginAlertSheet
來接受用戶選擇以決定程序是否退出。其函數原型定義如下:
void NSBeginCriticalAlertSheet (
NSString *title, //標題
NSString *defaultButton, //默認按鈕
NSString *alternateButton, //第二按鈕
NSString *otherButton, //其他按鈕
NSWindow *docWindow, //用于attach該sheet的窗體
id modalDelegate, //modal代理
SEL didEndSelector, //Selector結束時(sheet消失前)調用的modalDelegate中的函數
SEL didDismissSelector, //Selector結束時(sheet消失前)調用的modalDelegate中的函數
void *contextInfo, //傳給didEnd和didDismiss的額外數據
NSString *msg, //sheet的提示內容
...
);
我們把當前的類作為modalDelegate
。然后用其中的sheetClosed
函數來作為didEnd的回調函數。最后在applicationShouldTerminate
最后返回NSTerminateLater
來等待做進一步的處理。
在我們的實際判斷過程中。通過判斷用戶按下的是否是NSAlertDefaultReturn
來判斷用戶選擇的按鈕。如果是默認的退出按鈕,則給replyToApplicationShouldTerminate
傳YES以立刻退出,否則傳NO取消退出。
From: http://yeeyaa.me/articles/2011/03/confirm-application-quit-using-nsbeginalertsheet-as-delegate/