1

NSArrayController に裏打ちされたコア データにバインドされた NSPopupButton があります。NSPopupButton の選択も、コア データに裏打ちされた項目にバインドされます。バインディングはほとんど次のとおりです。

コア データ エンティティの NSArray 'A' --> アレイ コントローラ
配列コントローラ --> NSPopupButton.contentValues.arrangedObjects.name

コア データ エンティティの NSArray 'B' --> アレイ コントローラ
配列コントローラ --> NSPopupButton.selectedObject.methodOnObject.name

selectedObject には、オブジェクトを検索してそのオブジェクトを返す ID をルックアップするメソッドがあります。

-(MyWidget *)selectedWidget {

    return [MyCunningLookupMethod widgetForID:[[self widgetID] intValue]];
}

オブジェクトを別の方法で設定するのは、次のように簡単です。

-(void)setSWidget:(MyWidget *)anObj {

    [self setWidgetID:[anObj uid]];
}

ほとんどの場合、オブジェクトは利用可能な contentValues リスト内のオブジェクトと一致します。ただし、選択したオブジェクトの ID が 0 の場合があります。その場合、「未選択」というオプションを使用可能なリストに表示したいと考えています。オブジェクト ID が 0 の場合、別のオブジェクト (または何も返さない) を簡単に送り返すことができます。

これは「選択なしのプレースホルダー」で処理できますが、ユーザーが他のアイテムのいずれかを選択するとすぐに、選択されていないプレースホルダーがリストから削除されます。

ユーザーがアイテムを選択できるようにしたい、またはアイテムを選択しないことを選択できるようにしたい (つまり、「未選択」に戻す)。選択が変更されるたびにコアデータから取得した配列をウォークすることによってプログラムで NSPopupMenu 全体を作成する以外に、ユーザーが常に利用できる選択されていない状態を表すメニュー項目をリストに挿入する方法はありますか?

「選択されていません」という名前を除いて、すべて 0 ベースの値を持つエンティティ オブジェクトをコア データ ストアに追加することを検討しました。ただし、これは物事を行う正しい方法のようには感じられず、実際には、実際にはデータとの関連性がない空のオブジェクトがストアにあるという別の問題が発生します。

いつものように、どんな助けも大歓迎です。

解決

まあ、私はHobbes the Tige投稿されたものを正確にフォローしていませんでしたが、それは私が必要な場所に私を置いてくれました. IB にバインドする代わりに、選択の変更時にオブジェクトの配列を親配列または変更を開始するユーザー アクティビティに送信できるメソッドを作成することになりました。このメソッドは、NSPopupButton を適切なコア データ エンティティ情報で更新するだけで、一致するオブジェクトの selectedTag をバインドする IB を許可します。

これが方法です

+(void)createContentsForPopup:(NSPopUpButton *)aPopupButton
                withArray:(NSArray *)anObjectArray 
           addNotSelected:(BOOL)aFlag {

    [aPopupButton removeAllItems];

    if (aFlag) {    

        if (!anObjectArray || [anObjectArray count] == 0) {

           [aPopupButton addItemWithTitle:@"--- Not available ---"];
           [[aPopupButton itemAtIndex:0] setTag:0];

           return;
        }

        [aPopupButton addItemWithTitle:@"--- Not selected ---"];
        [[aPopupButton itemAtIndex:0] setTag:0];
    }

    NSSortDescriptor * sd = [NSSortDescriptor sortDescriptorWithKey:@"name"
                                                          ascending:YES];

    [anObjectArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sd]];

    for (id anObject in anObjectArray) {

        [aPopupButton addItemWithTitle:[anObject name]];

        int thisItem = [aPopupButton indexOfItemWithTitle:[anObject name]];

        [[aPopupButton itemAtIndex:thisItem] setTag:[[anObject uid] intValue]];
    }
}

name明らかに、これは、説明フィールドuid用の と一意の識別子用のを持つことに準拠して渡されるオブジェクトの配列に依存します。

ジョブ完了。:-)

4

1 に答える 1

2

これが最善の解決策であるとは言いませんが、これはアイデアです (おそらく微調整する必要があります)。

タイトル付きのメニュー項目を追加します。

- (void)insertItemWithTitle:(NSString *)title atIndex:(NSInteger)index

したがって、次のようになります。

[popupButton inserItemWithTitle:@"No selection" atIndex:0];

インデックス 0 に配置すると、一番上に配置されます。リストの一番下に表示したい場合は、次の方法を使用します。

- (void)addItemWithTitle:(NSString *)title

その後、アクション イベントを取得すると、インデックス 0 のアイテムを確認できます。インデックス 0 にある場合は、「選択なし」であることがわかります。

-(IBAction)popupSelectionAction:(id)sender {
     if (sender == popupButton) {
          //Check for "No selection"
          if ([popupButton indexOfSelectedItem] != 0) {
               //Update core data managed object value
          }
     }
}

または、addItemWithTitle を使用する場合は、アイテムの配列の最後のアイテムかどうかを確認します。

-(IBAction)popupSelectionAction:(id)sender {
     if (sender == popupButton) {
          //Check for "No selection"
          if ([popupButton indexOfSelectedItem] != ([popupButton numberOfItems]-1)) {
               //Update core data managed object value
          }
     }
}

クラス参照:

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSPopUpButton_Class/Reference/Reference.html

于 2011-04-07T21:24:19.710 に答える