對話框!開啟面板時忽略套件(Package)目錄
先前文章對話框!開啟與儲存面板功能已經理解如何使用NSOpenPanel
與NSSavePanel
方法,不過值得注意的是,當你設定只能選擇檔案類型時setCanChooseFiles:YES
,被封裝(package)類型的也會被視為單一檔案(其實它是目錄組成的),像我們使用的.app
檔案、.Bundle
檔案這些都是用目錄組成的。
Finder上選擇檔案後按下右鍵時會提示你要不要顯示套件內容
選擇就會進入該目錄看到整個結構,如果你不選擇時,Mac中會使用預設的解析程式去解析套件內容並執行主程式將App開啟,但從上面描述中能了解,它並不是真正的檔案
,接下來要將這種目錄
類型的套件在開啟面板中忽略,讓使用者無法去選擇這類型的檔案。
NSOpenSavePanelDelegate
開啟與儲存面板功能提供了Delegate,名為:NSOpenSavePanelDelegate,如此一來可以使用Delegate在開啟面板功能時能立即的接收到該物件的資料,並且將資料做一些預處理功能。
每當開啟面板時,會立即執行Delegate:- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url
,詢問讀到的檔案、目錄名稱是否接受在列表上面能夠被選擇(檔案、目錄),不想要被使用者選擇時只要返回YES
,之後就會在列表上顯示灰色代表不能被選擇:
上圖為經過處理後的列表,此功能將套件目錄
不能被使用者所選擇,所以呈現灰色,完整的程式如下:
//-----------start----------- //使用前記得在標頭檔中加入NSOpenSavePanelDelegate //<NSOpenSavePanelDelegate> // - (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url { BOOL showObject = YES; NSString *filename = [url relativePath]; NSError *error; NSDictionary* fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:[url relativePath] error:&error];//取得檔案/目錄 名稱的屬性 if (fileAttribs) { // check for packages if ([NSFileTypeDirectory isEqualTo:[fileAttribs objectForKey:NSFileType]])//判斷選擇的名稱是否為目錄結構 { if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO)//再判斷路徑名稱是否為套件目錄 showObject = YES;//返回YES代表不接受被選擇(呈灰色) else showObject = NO;//返回YES代表接受被選擇 } else { showObject = YES;//返回YES代表不接受被選擇(呈灰色) } } return showObject; } //------------end------------
此程式有參考Apple官方的NSOpenPanel – Choosing any file and ignoring packages,但因使用的Delegate在10.5後就不支援,所以將它改用新的Delegate並且將使用的相關物件方法都更正並支援OSX 10.9。