如何在旧版本的OS X上使用[NSAlert beginSheetModalForWindow:completionhandler:]

时间:2013-11-22 13:37:29

标签: objective-c cocoa objective-c-blocks

OS X Mavericks实施了一个新的API,以便更方便地显示NSAlert

- (void)beginSheetModalForWindow:(NSWindow *)sheetWindow completionHandler:(void (^)(NSModalResponse returnCode))handler

是否有一种简单的方法可以在OS X 10.8及更早版本支持的类别中创建类似的方法?

1 个答案:

答案 0 :(得分:9)

是的,您可以使用基于委托的API模拟类似的API。唯一棘手的部分是让所有演员阵容都正确,这样它就可以与ARC合作。这是NSAlert上的一个类别,它提供了一个向后兼容的基于块的API:

<强> NSAlert + BlockMethods.h

#import <Cocoa/Cocoa.h>
@interface NSAlert (BlockMethods)
-(void)compatibleBeginSheetModalForWindow: (NSWindow *)sheetWindow
                        completionHandler: (void (^)(NSInteger returnCode))handler;
@end

<强> NSAlert + BlockMethods.m

#import "NSAlert+BlockMethods.h"
@implementation NSAlert (BlockMethods)

-(void)compatibleBeginSheetModalForWindow: (NSWindow *)sheetWindow
                        completionHandler: (void (^)(NSInteger returnCode))handler
{
    [self beginSheetModalForWindow: sheetWindow
                     modalDelegate: self
                    didEndSelector: @selector(blockBasedAlertDidEnd:returnCode:contextInfo:)
                       contextInfo: (__bridge_retained void*)[handler copy] ];
}

-(void)blockBasedAlertDidEnd: (NSAlert *)alert
                  returnCode: (NSInteger)returnCode
                 contextInfo: (void *)contextInfo
{
    void(^handler)(NSInteger) = (__bridge_transfer void(^)(NSInteger)) contextInfo;
    if (handler) handler(returnCode);
}

@end

有关详细信息,请参阅我的NSAlertBlockMethods Github repo