objective c - NSCollectionView में चयन हाइलाइट करें




objective-c cocoa (4)

मेरे पास एक नाबालिग, लेकिन महत्वपूर्ण, अपवाद के साथ एक काम कर रहा NSCollectionView है। संग्रह के भीतर चयनित आइटम को प्राप्त करना और हाइलाइट करना।

मैंने यह सब हिम तेंदुए से पहले काम किया है, लेकिन ऐसा लगता है कि कुछ बदल गया है और मैं अपनी अंगुली को काफी जगह नहीं ले सकता, इसलिए मैंने अपने NSCollectionView को मूल परीक्षण में वापस ले लिया और एनएससीओलेक्शन व्यू बनाने के लिए ऐप्पल के दस्तावेज का पालन किया :

http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/CollectionViews/Introduction/Introduction.html

त्वरित दृश्य मार्गदर्शिका के बाद संग्रह दृश्य ठीक काम करता है। हालांकि, यह गाइड अन्य विकल्पों के अलावा चयन पर चर्चा नहीं करता है, "There are such features as incorporating image views, setting objects as selectable or not selectable and changing colors if they are selected"

उदाहरण के तौर पर इसका उपयोग करके मैं NSCollectionView को NSCollectionView में नियंत्रक कुंजी selectionIndexes NSCollectionView साथ बाध्य करने के अगले चरण में गया, यह सोचकर कि यह NSCollectionView और सरणी नियंत्रक के बीच किए गए किसी भी चयन को बाध्य करेगा और इस प्रकार NSCollectionView अधिसूचना को फायर कर देगा। मैंने आईबी में चयन करने योग्य NSCollectionView भी सेट किया है।

NSCollectionView लिए कोई चयन प्रतिनिधि नहीं NSCollectionView और अधिकांश कोको यूआई दृश्यों के विपरीत, कोई डिफ़ॉल्ट चयनित हाइलाइट नहीं होता है।

तो मेरी समस्या वास्तव में एक संबंधित मुद्दे पर आती है, लेकिन दो अलग-अलग प्रश्न हैं।

  1. मैं किसी आइटम का चयन कैप्चर कैसे करूं?
  2. मैं किसी आइटम की हाइलाइट कैसे दिखाऊं?

NSCollectionView प्रोग्रामिंग गाइड कुछ और बहुत दूर हैं और Google के माध्यम से अधिकतर खोज प्री-हिम तेंदुए कार्यान्वयन को खींचने के लिए दिखाई देती हैं, या एक अलग XIB फ़ाइल में दृश्य का उपयोग करती हैं।

बाद के लिए (दृश्य के लिए अलग XIB फ़ाइल), मुझे नहीं लगता कि यह एक पूर्व-आवश्यकता क्यों होनी चाहिए अन्यथा मुझे संदेह होगा कि ऐप्पल संग्रह दृश्य आइटम के समान बंडल में दृश्य शामिल नहीं करेगा।

मुझे पता है कि यह "पेड़ के लिए लकड़ी नहीं देख सकता" मुद्दा होगा - इसलिए मैं "दोह!" के लिए तैयार हूं पल।

हमेशा की तरह, किसी भी और सभी मदद की बहुत सराहना की।

अद्यतन 1

ठीक है, इसलिए मैंने चयनित आइटम ढूंढने का अनुमान लगाया, लेकिन अभी तक हाइलाइटिंग को समझना नहीं है। चयनित वस्तुओं को समझने में रुचि रखने के लिए (मान लीजिए कि आप ऐप्पल गाइड का पालन कर रहे हैं):

नियंत्रक में (मेरे परीक्षण मामले में ऐप प्रतिनिधि) मैंने निम्नलिखित जोड़ा:

जागने में FromNib

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

नई विधि

-(void)observeValueForKeyPath:(NSString *)keyPath 
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void *)context
{
    if([keyPath isEqualTo:@"selectionIndexes"])
    {
        if([[personArrayController selectedObjects] count] > 0)
        {
            if ([[personArrayController selectedObjects] count] == 1)
            {
                personModel * pm = (PersonModel *) 
                       [[personArrayController selectedObjects] objectAtIndex:0];
                NSLog(@"Only 1 selected: %@", [pm name]);
            }
            else
            {
                // More than one selected - iterate if need be
            }
        }
    }

गैर जीसी के लिए dealloc भूलना मत भूलना

-(void)dealloc
{
    [personArrayController removeObserver:self 
                               forKeyPath:@"selectionIndexes"];
    [super dealloc];
}

अभी भी हाइलाइट रिज़ॉल्यूशन की तलाश है ...

अद्यतन 2

मैकैटॉमी की सलाह ली लेकिन अभी भी एक मुद्दा था। यह देखने के लिए प्रासंगिक वर्ग विधियों को पोस्ट करना कि मैं कहां गलत हो गया हूं।

MyView.h

#import <Cocoa/Cocoa.h>

@interface MyView : NSView {
    BOOL selected;
}

@property (readwrite) BOOL selected;

@end

MyView.m

#import "MyView.h"

@implementation MyView

@synthesize selected;

-(id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
    }
    return self;
}

-(void)drawRect:(NSRect)dirtyRect
{
    NSRect outerFrame = NSMakeRect(0, 0, 143, 104);
    NSRect selectedFrame = NSInsetRect(outerFrame, 2, 2);

    if (selected)
        [[NSColor yellowColor] set];
    else
        [[NSColor redColor] set];

    [NSBezierPath strokeRect:selectedFrame];
}

@end

MyCollectionViewItem.h

#import <Cocoa/Cocoa.h>
@class MyView;

@interface MyCollectionViewItem : NSCollectionViewItem {

}

@end

"MyCollectionViewItem.m *

#import "MyCollectionViewItem.h"
#import "MyView.h"

@implementation MyCollectionViewItem

-(void)setSelected:(BOOL)flag
{

    [(MyView *)[self view] setSelected:flag];
    [(MyView *)[self view] setNeedsDisplay:YES];
}

@end

ऐसा करना मुश्किल नहीं है। सुनिश्चित करें कि इंटरफ़ेस बिल्डर में NSCollectionView के लिए "चयन" सक्षम है। फिर एनएसवी व्यूक्लास में जो आप अपने प्रोटोटाइप व्यू के लिए उपयोग कर रहे हैं, "चयनित" नामक एक संपत्ति घोषित करें:

@property (readwrite) BOOL selected;

यहां अपडेट किया गया कोड: (अतिरिक्त कॉल जोड़ा गया)

Subclass NSCollectionViewItem और ओवरराइड -सेट चयनित:

- (void)setSelected:(BOOL)flag
{
    [super setSelected:flag];
    [(PrototypeView*)[self view] setSelected:flag];
    [(PrototypeView*)[self view] setNeedsDisplay:YES];
}

फिर आपको अपने प्रोटोटाइप व्यू के ड्रॉरेक्ट में कोड जोड़ने की आवश्यकता है: हाइलाइट आकर्षित करने के लिए विधि:

- (void)drawRect:(NSRect)dirtyRect 
{
    if (selected) {
       [[NSColor blueColor] set];
       NSRectFill([self bounds]);
    }
}

यह सिर्फ चयनित होने पर नीले रंग में दृश्य भरता है, लेकिन इसे किसी भी तरह से हाइलाइट करने के लिए अनुकूलित किया जा सकता है। मैंने इसे अपने स्वयं के ऐप्स में उपयोग किया है और यह बहुत अच्छा काम करता है।


चूंकि मौजूदा उत्तरों में से कोई भी मेरे लिए बहुत अच्छा काम नहीं करता है, इसलिए यहां मेरा लेना है। SelectViewlectionViewItem को CollectionView आइटम के उप-वर्ग को बदलें। यहां यह कोड है। एक बाइंडेबल टेक्स्ट के साथ आता है आपके टेक्स्ट लेबल टेक्स्ट को हुक करने के लिए रंग संपत्ति रंग बाध्यकारी।

@implementation SelectableCollectionViewItem

+ (NSSet *)keyPathsForValuesAffectingTextColor
{
    return [NSSet setWithObjects:@"selected", nil];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.wantsLayer = YES;
}

- (void) viewDidAppear
{
    // seems the inital selection state is not done by Apple in a KVO compliant manner, update background color manually
    [self updateBackgroundColorForSelectionState:self.isSelected];
}

- (void)updateBackgroundColorForSelectionState:(BOOL)flag
{
    if (flag)
    {
        self.view.layer.backgroundColor = [[NSColor alternateSelectedControlColor] CGColor];
    }
    else
    {
        self.view.layer.backgroundColor = [[NSColor clearColor] CGColor];
    }
}

- (void)setSelected:(BOOL)flag
{
    [super setSelected:flag];
    [self updateBackgroundColorForSelectionState:flag];
}

- (NSColor*) textColor
{
    return self.selected ? [NSColor whiteColor] : [NSColor textColor];
}

यदि आप अपने प्रोटोटाइप व्यू के लिए एनएसवी व्यू को उपclass नहीं कर रहे हैं, तो आप एक और तरीका भी जा सकते हैं।

आपके उपclassed NSCollectionViewItem ओवरराइड setSelected:

- (void)setSelected:(BOOL)selected
{
    [super setSelected:selected];
    if (selected)
        self.view.layer.backgroundColor = [NSColor redColor].CGColor;
    else
        self.view.layer.backgroundColor = [NSColor clearColor].CGColor;
}

और निश्चित रूप से, जैसा कि मेरे सामने सभी बुद्धिमान लोगों ने कहा है, सुनिश्चित करें कि इंटरफेस बिल्डर में एनएससीओलेक्शन व्यू के लिए "चयन" सक्षम है।


यदि एक अलग पृष्ठभूमि रंग एक हाइलाइट के रूप में पर्याप्त होगा, तो आप संग्रह आइटम दृश्य के लिए रूट आइटम के रूप में बस एक NSBox का उपयोग कर सकते हैं। अपनी पसंद के हाइलाइट रंग के साथ एनएसबीक्स भरें। एनएसबीक्स को कस्टम पर सेट करें ताकि भर काम करे। एनएसबीक्स को पारदर्शी में सेट करें।

फ़ाइल मालिक (संग्रह आइटम) के चयनित गुण में एनएसबीक्स की पारदर्शिता विशेषता को बाध्य करें एनएसएनगेटबोलियन के पारदर्शी बाध्यकारी के लिए मूल्य ट्रांसफार्मर सेट करें।

मैंने इंटरफेस बिल्डर स्क्रीनशॉट संलग्न करने की कोशिश की लेकिन मुझे बीसीओ को खारिज कर दिया गया मैं एक नौसिखिया हूं :-(





nscollectionviewitem