NSAlert用于弹出一个确认对话框,在程序中被广泛地使用。常见的场景是用户删除数据,会弹出对话框给用户确认,免得用户不小心导致了误操作。
NSAlert可以采用Modal Window的方式展示
如图:
代码如下:
//采用Modal Window的方式展示 - (IBAction)ShowNSAlertWindow:(id)sender { NSAlert *alert = [NSAlert alertWithMessageText:@"messageText" defaultButton:@"defaultButton" alternateButton:@"alternateButton" otherButton:@"otherButton" informativeTextWithFormat:@"informativeText"]; NSUInteger action = [alert runModal]; //响应window的按钮事件 if(action == NSAlertDefaultReturn) { NSLog(@"defaultButton clicked!"); } else if(action == NSAlertAlternateReturn ) { NSLog(@"alternateButton clicked!"); } else if(action == NSAlertOtherReturn) { NSLog(@"otherButton clicked!"); } }
NSAlert也可以采用Sheet的方式展示
如图:
代码如下:
//采用Sheet的方式展示 - (IBAction)ShowNSAlertSheet:(id)sender { NSMutableDictionary * extrasDict = [[NSMutableDictionary alloc] init]; [extrasDict setObject:@"http://www.baidu.com" forKey:@"link"]; NSAlert *alert = [NSAlert alertWithMessageText:@"messageText" defaultButton:@"defaultButton" alternateButton:@"alternateButton" otherButton:@"otherButton" informativeTextWithFormat:@"informativeText"]; //__bridge_retained for arc [alert beginSheetModalForWindow:self.window modalDelegate:self didEndSelector:@selector(alertSheetDidEnd:returnCode:contextInfo:) contextInfo:(__bridge void *)(extrasDict )]; } //响应Sheet的按钮事件 - (void)alertSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { if (returnCode == NSAlertDefaultReturn) { NSLog(@"alternateButton clicked!"); //show you how to use contextInfo //__bridge_transfer for arc NSString *url = [(__bridge NSDictionary*)contextInfo objectForKey:@"link"]; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]]; } else if(returnCode == NSAlertAlternateReturn ) { NSLog(@"alternateButton clicked!"); } else if(returnCode == NSAlertOtherReturn) { NSLog(@"otherButton clicked!"); } }
源代码
=====================华丽的分割线=====================
可以说NSAlert是标准的,中规中矩,几乎可以应用到所有需要提示框的地方。但我们很难通过继承的方式来扩展NSAlert的功能,事实上NSAlert的设计初衷就是提供一个提示框标准,并不希望用户通过继承去自定义。
在特定的应用程序中,我们经常希望可以自己提供一个自定义窗口,并可以像NSAlert那样采用Modal Window的方式或者采用Sheet的方式来展示。比如黑色主题的程序希望这个NSAlert窗口是黑色的,而不是标准的灰白色,这样才显得和谐。
下面我通过继承NSObject的方式来实现一个SYXAlert类,SYXAlert类采用一个自定义的窗口SYXAlert来模拟NSAlert。
SYXAlert可以采用Modal Window的方式展示
如图:
代码如下:
//采用Window的方式展示 - (IBAction)ShowSYXAlertWindow:(id)sender { SYXAlert *alert = [SYXAlert alertWithMessageText:@"SYXAlertWindow" okButton:@"Ok" cancelButton:@"Cancel"]; NSInteger action = [alert runModal]; if(action == SYXAlertOkReturn) { NSLog(@"SYXAlertOkButton clicked!"); } else if(action == SYXAlertCancelReturn ) { NSLog(@"SYXAlertCancelButton clicked!"); } }
注:modal对话框窗口左上角是没有Close、Minimize、Resize这些按钮的,所以在xib中去掉这些按钮
SYXAlert也可以采用Sheet的方式展示
如图:
代码如下:
//采用Sheet的方式展示 - (IBAction)ShowSYXAlertSheet:(id)sender { NSMutableDictionary * extrasDict = [[NSMutableDictionary alloc] init]; [extrasDict setObject:@"http://www.baidu.com" forKey:@"link"]; SYXAlert *alert = [SYXAlert alertWithMessageText:@"SYXAlertSheet" okButton:@"Ok" cancelButton:@"Cancel"]; [alert beginSheetModalForWindow:self.window modalDelegate:self didEndSelector:@selector(alertSheetDidEnd:returnCode:contextInfo:) contextInfo:(__bridge void*)extrasDict]; } //响应Sheet的按钮事件 - (void)alertSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { if (returnCode == SYXAlertOkReturn) { NSLog(@"SYXAlertOkButton clicked!"); //show you how to use contextInfo //__bridge_transfer for arc NSString *url = [(__bridge NSDictionary*)contextInfo objectForKey:@"link"]; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]]; } else if(returnCode == SYXAlertCancelReturn ) { NSLog(@"SYXAlertCancelButton clicked!"); } }
注:xib的window属性有一个选项,就是visible at launch,默认是勾选,窗口无法采用sheet的方式附在父窗口上;勾掉,窗口才能采用sheet的方式附在父窗口上