我需要打开或保存对文件对话框,有一个选择文件后缀的功能。如下图:
默认的NSOpenPanel,、NSSavePanel是没有的。
===========
在网上找到一种方式,就是通过NSOpenPanel,、NSSavePanel的setAccessoryView方法
导入其他nib文件中的示图,功能基本都做出来了。FileDialog.xib文件如下:
FileDialog.h文件如下:#pragma once
#import <Foundation/Foundation.h>@interface  CExtAccessory: NSObject {
IBOutlet NSOpenPanel* m_pnlOpen;
IBOutlet NSSavePanel* m_pnlSave;
IBOutlet NSView* m_rootView;
IBOutlet NSComboBox* m_edtFilters;
NSMutableArray* m_filters;
}
-(id)initFromNib:(bool)isOpen :(NSView*) pnl;
//set filters = nil when all file;
//or set filters = array of [@"mp3",@"pdf",@"xml"];
-(void)addExtFilter:(NSString*)description :(NSArray*)filters;
-(void)setFilterIndex:(int) index;
-(int)getFilterIndex;
@end@interface CExtOpenPanel: NSOpenPanel {
CExtAccessory* m_accessory;
}
-(void)InitAccessory;
-(void)addExtFilter:(NSString*)description :(NSArray*)filters;
-(void)setFilterIndex:(int) index;
-(int)getFilterIndex;
@end@interface CExtSavePanel: NSSavePanel {
CExtAccessory* m_accessory;
}
-(void)InitAccessory;
-(void)addExtFilter:(NSString*)description :(NSArray*)filters;
-(void)setFilterIndex:(int) index;
-(int)getFilterIndex;
@endFileDialog.m文件如下:#import "FileDialog.h"#define NIB_NAMED @"FileDialog" //FileDialog.xib@interface FilterItem: NSObject {
@public
NSString* description;
NSArray* filters;
}
+(id)new:(NSString*)description :(NSArray*)filters;
@end@implementation FilterItem
+(id)new:(NSString*)description :(NSArray*)filters {
FilterItem* instance = [[FilterItem alloc] init];
instance->description = description;
instance->filters = filters;
return instance;
}
@end@implementation CExtAccessory
-(id)initFromNib:(bool)isOpen :(NSView*) pnl {
self = [super init];

[NSBundle loadNibNamed:NIB_NAMED owner:self];
//[m_edtFilters setAutoresizingMask:NSViewNotSizable];

if(isOpen) {
m_pnlOpen = (NSOpenPanel*)pnl;
[m_pnlOpen setAccessoryView:m_edtFilters];
//[m_pnlOpen setAllowedFileTypes:[NSArray arrayWithObjects:@"pdf",@"mp3",@"rtf",nil]];
}
else {
m_pnlSave = (NSSavePanel*)pnl;
[m_pnlSave setAccessoryView:m_edtFilters];
}

return self;
}-(void)addExtFilter:(NSString*)description :(NSArray*)filters {
if(!m_filters) {
m_filters = [NSMutableArray array];
}
FilterItem* item = [[FilterItem new:description :filters] autorelease];
[m_filters addObject:item];
[m_edtFilters addItemWithObjectValue:description];
}
-(void)setFilterIndex:(int) index {
if(!m_filters) return;
FilterItem* item = [m_filters objectAtIndex:index];
if(!item) return;
if(m_pnlOpen) {
[m_pnlOpen setAllowedFileTypes:item->filters];
}
else if(m_pnlSave) {
[m_pnlSave setAllowedFileTypes:item->filters];
}
[m_edtFilters selectItemAtIndex:index];
}
-(int)getFilterIndex {
return (int)[m_filters count];
}#pragma  dataSource#pragma  delegate
-(void)comboBoxSelectionDidChange:(NSNotification *)notification {
if([notification object] == m_edtFilters) {
[self setFilterIndex:(int)[m_edtFilters indexOfSelectedItem]];
}
}
@end@implementation CExtOpenPanel
-(void)InitAccessory {
if(m_accessory) return;
m_accessory = [[[CExtAccessory alloc] initFromNib:true :(NSView*)self] autorelease];
}-(void)addExtFilter:(NSString*)description :(NSArray*)filters {
if(!m_accessory) return;
[m_accessory addExtFilter:description :filters];
}
-(void)setFilterIndex:(int) index {
if(!m_accessory) return;
[m_accessory setFilterIndex:index];
}
-(int)getFilterIndex {
if(!m_accessory) return 0;
return [m_accessory getFilterIndex];
}
@end@implementation CExtSavePanel
-(void)InitAccessory {
if(m_accessory) return;
m_accessory = [[[CExtAccessory alloc] initFromNib:true :(NSView*)self] autorelease];
}-(void)addExtFilter:(NSString*)description :(NSArray*)filters {
if(!m_accessory) return;
[m_accessory addExtFilter:description :filters];
}
-(void)setFilterIndex:(int) index {
if(!m_accessory) return;
[m_accessory setFilterIndex:index];
}
-(int)getFilterIndex {
if(!m_accessory) return 0;
return [m_accessory getFilterIndex];
}
@end
====================
这个功能调用如下: CExtOpenPanel* pnl = [[CExtOpenPanel alloc] init];
[pnl InitAccessory];
[pnl addExtFilter:@"*.mp3 | *.pdf | *.rtf" :[NSArray arrayWithObjects:@"mp3", @"pdf", @"rtf", nil]];
[pnl addExtFilter:@"*.mp3" :[NSArray arrayWithObjects:@"mp3", nil]];
[pnl addExtFilter:@"*.pdf" :[NSArray arrayWithObjects:@"pdf", nil]];
[pnl setFilterIndex:0];
[pnl runModal];

[pnl release];
效果是出来了,刚runModal时只显示mp3、pdf、rtf文件,,其他格式恢化..如图
当此时,我没按确定之前,下拉框重新选择后缀,我想只显示mp3类型时,对话框并没有相应地做改变.如图
可能我对mac的run loop以及事件机制
不了解一个NSOpenPanel,、NSSavePanel的setAllowedFileTypes只有在runModal之前调用才有效果
调用了runModal之后再调用setAllowedFileTypes,不会再有效果,是么?