0

awakeFromNib私は持っています:

[projectArrayController addObserver:self
                    forKeyPath:@"selectionIndexes"
                       options:NSKeyValueObservingOptionNew
                       context:nil];

そして、私が持っています:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change context:(void *)context {
    NSLog(@"%@ forObject: %@",keyPath, object);
    if([keyPath isEqualTo:@"selectionIndexes"]){
        NSUInteger numberOfSelected = [[projectArrayController selectedObjects] count];
        if(numberOfSelected >0){
            if (numberOfSelected == 1){
                ProjectModel *pm =  (ProjectModel *)[[projectArrayController selectedObjects] objectAtIndex:0];
                [pm setSelected:YES];
            }
        }
    }
}

ログ:selectionIndexes forObject: <NSArrayController: 0x1001cb6e0>[object class: ProjectModel, number of selected objects: 1]

しかし、プログラムを実行すると、実際には他のものをクリックすることはできません。どうしてこれなの?どのタイプのデリゲートを使用すればよいですか? これまで、tableviewデリゲートとcollectionviewデリゲートを使ってみました。

または、NSCollectionView をファーストレスポンダーにするにはどうすればよいですか?

4

1 に答える 1

1

私はこれを機能させましたが、簡単ではありません。NSView のサブクラスであるコレクション ビューのサブビューをサブクラス化する必要があります。これが私のサブクラスの外観です...

@implementation GiggleCollectionSubView
@synthesize itIsSelected;

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        itIsSelected = NO;
    }
    return self;
}

- (void)dealloc {
    [super dealloc];
}

- (void)awakeFromNib {

}

- (void)drawRect:(NSRect)rect {
    [[NSColor clearColor] set];
    if (self.itIsSelected) {
        [NSGraphicsContext saveGraphicsState];
        NSSetFocusRingStyle(NSFocusRingAbove);
        [[NSBezierPath bezierPathWithRect:NSInsetRect([self bounds], 2, 2)] fill];
        [NSGraphicsContext restoreGraphicsState];
    } else {
        [[NSBezierPath bezierPathWithRect:[self bounds]] fill];
    }
}

- (void)mouseDown:(NSEvent *)theEvent {
    if ([theEvent clickCount]==1) {
        if (![self itIsSelected]) {
            [[[NSApp delegate] giggleWindowController] clearCollectionView];
            [self setItIsSelected:YES];
            [self setNeedsDisplay:YES];
            [[[NSApp delegate] giggleWindowController] updateSelectionIndexes];
            [[[NSApp delegate] giggleWindowController] showSelectedImage];
        }
    }
}

@end

itIsSelected というインスタンス変数があることがわかります。これが鍵です。すべてを機能させる変数を手動で管理します。最初に drawRect メソッドで、サブビューが選択されていることを示すフォーカス リングがサブビューに描画されているかどうかを判断します。次の mouseDown: メソッドは、ユーザーがサブビューをクリックして選択したことを検出する場所です。そこで、配列コントローラーの selectionIndexes を手動で管理し、すべてのサブビューの itIsSelected インスタンス変数を手動で管理します。まず、メソッド clearCollectionView のすべてのサブビューに対して itIsSelected を NO に設定します。次に、クリックされたサブビューの itIsSelected を YES に設定します。次に、配列コントローラーの selectionIndexes を更新し、selectedObject に基づいて何かを行います (たとえば、showSelectedImage で)。これがその2つの方法です。

-(void)clearCollectionView {
    NSArray* cvViews = [artistImagesCV subviews];
    for (GiggleCollectionSubView* aView in cvViews) {
        if ([aView itIsSelected]) {
            [aView setItIsSelected:NO];
            [aView setNeedsDisplay:YES];
        }
    }
}

-(void)updateSelectionIndexes {
    NSArray* cvViews = [artistImagesCV subviews];
    NSMutableIndexSet* indexes = [NSMutableIndexSet indexSet];

    NSUInteger counter = 0;
    for (GiggleCollectionSubView* aView in cvViews) {
        if ([aView itIsSelected]) [indexes addIndex:counter];
        counter++;
    }
    [googleImagesArrayController setSelectionIndexes:(NSIndexSet*)indexes];
}

注:私のサブビューには、画像ビューもあります。それをサブクラス化し、その mouseDown メソッドで同様のことを行う必要がありました。

とにかく、これが役立つことを願っています。あなたが試みていた方法を使用して動作させることができなかったので、説明に従って手動で行いました。幸運を。

于 2013-01-25T04:01:38.933 に答える