2012-03-23 13 views
5

के अंदर एक कस्टम NSTextField में मेरे पास व्यू-आधारित NSTableView है। तालिका में प्रत्येक दृश्य में एक कस्टम टेक्स्ट फ़ील्ड है।माउसडाउन: एक NSTableView

जब उपयोगकर्ता तालिका के दृश्य के अंदर टेक्स्ट फ़ील्ड (लेबल) पर क्लिक करता है तो एक क्रिया को आग लगाना चाहती है (कल्पना करें कि प्रत्येक तालिका कक्ष में एक कस्टम कार्रवाई के साथ हाइपरलिंक हो)।

मैंने माउस ईवेंट को पकड़ने के लिए एक मूल NSTextField सबक्लास बनाया है। हालांकि, वे केवल दूसरे क्लिक पर आग लगते हैं, न कि पहले क्लिक पर।

मैंने NSButton का उपयोग करने की कोशिश की और वह तुरंत आग लग गई।

यहाँ कस्टम लेबल के लिए कोड है:

@implementation HyperlinkTextField 

- (void)mouseDown:(NSEvent *)theEvent { 
    NSLog(@"link mouse down"); 
} 

- (void)mouseUp:(NSEvent *)theEvent { 
    NSLog(@"link mouse up"); 
} 

- (BOOL)acceptsFirstResponder { 
    return YES; 
} 

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { 
    return YES; 
} 
@end 

उत्तर

6

यह पता चला कि NSTableView और NSOultineViewNSTextField उदाहरण के लिए की तुलना में अलग एक NSButton के लिए पहले प्रत्युत्तर स्थिति संभाल।

कुंजी लेबल पहले क्लिक करने के लिए प्रतिक्रिया करने के लिए एक बटन की तरह [NSResponder validateProposedFirstResponder:forEvent:] अधिलेखित करने के लिए अपने कस्टम पाठ क्षेत्र वर्ग के मामले में YES वापस जाने के लिए है पाने के लिए।

प्रलेखन:

http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/NSResponder/validateProposedFirstResponder:forEvent:

1

क्योंकि तालिका दृश्य पहले प्रत्युत्तर, जो यह होना चाहिए या जब आप क्लिक पंक्ति नहीं बदलेगा है व्यवहार है कि आप देख रहे हैं है लेबल पर - यह वह व्यवहार है जिसे उपयोगकर्ता तालिका पंक्ति पर क्लिक करते समय अपेक्षा करता है। लेबल को उप-वर्गीकृत करने के बजाय, मुझे लगता है कि तालिका दृश्य को उप-वर्ग करना और माउस ओवरराइड करना बेहतर होगा: वहां। माउसडाउन के सुपर के कार्यान्वयन को कॉल करने के बाद: आप यह जांचने के लिए हिट टेस्ट कर सकते हैं कि उपयोगकर्ता लेबल पर क्लिक करता है।

@implementation CustomTable 

- (void)mouseDown:(NSEvent *)theEvent 
{ 
    [super mouseDown:theEvent]; 
    NSPoint point = [self convertPoint:theEvent.locationInWindow fromView:nil]; 
    NSView *theView = [self hitTest:point]; 
    if ([theView isKindOfClass:[NSTextField class]]) 
    { 
     NSLog(@"%@",[(NSTextField *)theView stringValue]); 
    } 
} 

@end 
+0

धन्यवाद, मैं कोशिश करूँगा। एक सवाल: पहला क्लिक एनएसबटन के साथ काम करता है (तालिका पंक्ति उस मामले में नहीं चुनी जाती है)। क्या उस व्यवहार का अनुकरण करने का कोई तरीका है? – Mark

+0

शायद वहां है, लेकिन मुझे यह नहीं पता। मैंने सोचा होगा कि स्वीकार करने के लिए हाँ वापस लौटना फर्स्टमाउस और/या स्वीकार करता है फर्स्ट रेस्पॉन्डर ने ऐसा किया होगा। – rdelmar

+0

यदि आप एक बटन के साथ प्राप्त व्यवहार चाहते हैं, तो बस एक बटन का उपयोग क्यों न करें? आप सीमा को बंद कर सकते हैं, और यह वैसे भी एक सीमा रहित लेबल की तरह दिखता है। यदि आप सीमा चाहते हैं, तो आप एनएसबीओक्स में एक सीमा रहित बटन एम्बेड कर सकते हैं। – rdelmar

7

एक ही समस्या थी। यहां स्वीकार किया गया जवाब मेरे लिए काम नहीं करता था। बहुत संघर्ष करने के बाद, जब मैंने आईबी में तालिका दृश्य के "हाइलाइट" विकल्प के लिए "स्रोत सूची" के दूसरे विकल्प के साथ डिफ़ॉल्ट "नियमित" के खिलाफ "कोई नहीं" चुना, तो यह जादूगर रूप से काम करता था!

संपादित करें: स्वीकृत उत्तर भ्रामक साबित होता है क्योंकि तालिका दृश्य के लिए विधि को अधिभारित किया जाना चाहिए, न कि टेक्स्ट फ़ील्ड के लिए, जैसा कि उत्तर बताता है। इसे https://stackoverflow.com/a/13579469/804616 पर अधिक स्पष्ट रूप से दिया गया है लेकिन किसी भी मामले में, अधिक विशिष्ट होने के कारण थोड़ा हैकी लगता है।

+0

यह काम नहीं करता है। शायद आपने कुछ और किया –

+2

ऐसा लगता है कि यह वास्तव में काम करता है। मैं माउसअप ट्रिगर करने की कोशिश कर रहा था, लेकिन यह किसी भी तरीके से काम नहीं करता है। MouseDown –

+0

दोनों के साथ काम करता है, जबकि यह काम करता है, तो क्या होगा यदि आप स्रोत सूची तालिका दृश्य शैली का उपयोग करने के लिए तालिका दृश्य चाहते हैं? –

1

ठीक उसी स्थिति में, true/YES के लिए एक NSButton साथ transparent सेट embedding मेरे लिए काम किया।

class LinkButton: NSTextField { 

    var clickableButton:NSButton? 

    override func viewDidMoveToSuperview() {    
     let button = NSButton() 
     self.addSubview(button) 

     //setting constraints to cover the whole textfield area (I'm making use of SnapKit here, you should add the constraints your way or use frames 
     button.snp_makeConstraints { (make) -> Void in 
      make.edges.equalTo(NSEdgeInsetsZero) 
     } 
     button.target = self 
     button.action = Selector("pressed:") 
     button.transparent = true 
    } 

    func pressed(sender:AnyObject) { 
     print("pressed") 
    } 
0

आप संपादन पाठ क्षेत्र शुरू करने के लिए window.makeFirstResponser (myTextfield) का उपयोग करें। आप इस संदेश को ओवरराइड माउसडाउन से भेजें (withEvent TheEvent: NSEvent) विधि

संबंधित मुद्दे