ユーザーが NSTableView のどの列を右クリックして表示するかを選択できるようにする方法を知っている人はいますか? iTunesと同じように。
3 に答える
私はこれを実装しました。以下はサブクラス化せずに使用できるはずです。
最初に IB で空のメニューを実装し、Table Header View のメニュー出力に接続します。
このメソッド (awakeFromNib から呼び出される) は、ヘッダーからメニューのコンテンツを構築します (ユーザーがプライマリ列を非表示にしないようにするためのテストが含まれています)。
- (void)initViewHeaderMenu:(id)view {
//create our contextual menu
NSMenu *menu = [[view headerView] menu];
//loop through columns, creating a menu item for each
for (NSTableColumn *col in [view tableColumns]) {
if ([[col identifier] isEqualToString:COLUMNID_NAME])
continue; // Cannot hide name column
NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:[col.headerCell stringValue]
action:@selector(toggleColumn:) keyEquivalent:@""];
mi.target = self;
mi.representedObject = col;
[menu addItem:mi];
}
return;
}
これにより、実際の非表示/非表示を行うために以下が呼び出されます
- (void)toggleColumn:(id)sender {
NSTableColumn *col = [sender representedObject];
[col setHidden:![col isHidden]];
}
また、メニューのデリゲートを設定し、状態を設定するために以下を実装する必要があります:-
#pragma mark NSMenu Delegate Methods
-(void)menuWillOpen:(NSMenu *)menu {
for (NSMenuItem *mi in menu.itemArray) {
NSTableColumn *col = [mi representedObject];
[mi setState:col.isHidden ? NSOffState : NSOnState];
}
}
このブログ投稿に基づいて Milliways の優れた回答を拡張し、次の機能を追加しました。
- 表示されている列にチェックマークを表示する
- を使用して設定を永続化します
NSUserDefaults
初期設定:
// Your intial Startup code
[self setupHeaderMenu:self.yourTableView];
メニューの作成:
重要:col.identifier
これが機能するためには、IB の各テーブル ビュー列に「Identify Identifier」を設定する必要があるためです。
#pragma mark - Show Hide Columns
- (void)setupHeaderMenu:(NSTableView *)tableView {
NSDictionary *savedCols = [[NSUserDefaults standardUserDefaults] dictionaryForKey:kUserDefaultsKeyVisisbleColumns];
NSMenu *menu = [NSMenu new];
for (NSTableColumn *col in tableView.tableColumns) {
NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:[col.headerCell stringValue]
action:@selector(toggleColumn:)
keyEquivalent:@""];
mi.target = self;
if(savedCols){
BOOL isVisible = [savedCols[col.identifier] boolValue];
[col setHidden:!isVisible];
}
mi.state = (col.isHidden ? NSOffState: NSOnState);
mi.representedObject = col;
[menu addItem:mi];
}
tableView.headerView.menu = menu;
return;
}
トグル方式
トグル メソッドは、新しい構成をNSUserDefaults
- (void)toggleColumn:(NSMenuItem *)menu {
NSTableColumn *col = menu.representedObject;
BOOL shouldHide = !col.isHidden;
[col setHidden:shouldHide];
menu.state = (col.isHidden ? NSOffState: NSOnState);
NSMutableDictionary *cols = @{}.mutableCopy;
for( NSTableColumn *column in self.yourTableView.tableColumns){
cols[column.identifier] = @(!column.isHidden);
}
[[NSUserDefaults standardUserDefaults] setObject:cols forKey:kUserDefaultsKeyVisibleColumns];
if(shouldHide){
[self.yourTableView sizeLastColumnToFit];
} else {
[self.yourTableView sizeToFit];
}
}
メニューデリゲート
-(void)menuWillOpen:(NSMenu *)menu {
for (NSMenuItem *mi in menu.itemArray) {
NSTableColumn *col = [mi representedObject];
[mi setState:col.isHidden ? NSOffState : NSOnState];
}
}
結果
したがって、各列をオン/オフにすると、アプリを再起動した後でも構成が保存されます。
NSMenu
列を持つテーブルのヘッダーにを添付し、NSMenuItems
右クリックで開く必要があります。NSViewController
テーブルビューをサブクラス化してアタッチすることでこれを行いました。クラスもNSMenuDelegate
. 以下の例。
.h ファイル:
@interface UserManagedColumnsTableViewController : NSViewController <NSMenuDelegate>
@property (weak) IBOutlet NSTableView *tableView;
@end
.m ファイル:
@interface UserManagedColumnsTableViewController ()
- (void)toggleColumn:(id)sender;
@end
@implementation UserManagedColumnsTableViewController
- (void)awakeFromNib {
[super awakeFromNib];
NSMenu *columnsMenu = [[NSMenu alloc] initWithTitle:@""];
for (NSTableColumn *column in self.tableView.tableColumns) {
NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:[column.headerCell stringValue]
action:@selector(toggleColumn:)
keyEquivalent:@""];
menuItem.target = self;
menuItem.representedObject = column;
[columnsMenu addItem:menuItem];
}
columnsMenu.delegate = self;
[self.tableView.headerView setMenu:columnsMenu];
}
#pragma mark - NSMenuDelegate conformance
- (void)menuWillOpen:(NSMenu *)menu {
for (NSMenuItem *menuItem in menu.itemArray) {
NSTableColumn *column = [menuItem representedObject];
[menuItem setState:column.isHidden ? NSOffState : NSOnState];
}
}
#pragma mark - Private Methods
- (void)toggleColumn:(id)sender {
NSTableColumn *column = [sender representedObject];
[column setHidden:![column isHidden]];
}
@end