2010-02-03 14 views
11

क्या कोई उपयोगकर्ता NSTextField के सभी टेक्स्ट को चुनने का तरीका सुझा सकता है जब उपयोगकर्ता इसे क्लिक करता है?फोकस पर NSTextField का चयन करें

मुझे NSTextField उप-वर्ग के लिए सुझाव मिल गए और फिर mouseDown या firstResponder का उपयोग करें, लेकिन यह अब मेरे कौशल से परे है। तो मैं उम्मीद कर रहा था कि या तो एक आसान समाधान होगा या कोई भी आवश्यक कदमों का विस्तार करने के लिए पर्याप्त दयालु हो सकता है।

उत्तर

23

कोई आसान समाधान नहीं है, आपको अपनी इच्छा के अनुसार NSTextField उपclass करने की आवश्यकता है। यदि आपको कोको में कुछ भी उपयोगी करना है तो आपको सबक्लासिंग को संभालने का तरीका सीखना होगा।

टेक्स्ट फ़ील्ड उपclass के लिए अपेक्षाकृत जटिल हो सकते हैं क्योंकि NSTextField वास्तविक संपादन को संभालने के लिए फील्ड संपादक नामक एक अलग NSTextView ऑब्जेक्ट का उपयोग करता है। यह पाठ दृश्य के लिए NSWindow ऑब्जेक्ट द्वारा वापस किया गया है और इसे पृष्ठ पर सभी टेक्स्ट फ़ील्ड के लिए फिर से उपयोग किया जाता है।

किसी भी NSResponder उपवर्ग की तरह, NSTextField तरीकों -acceptsFirstResponder और -becomeFirstResponder प्रतिक्रिया करता है। इन्हें तब कहा जाता है जब खिड़की किसी विशेष नियंत्रण या दृश्य पर ध्यान देना चाहती है। यदि आप इन दोनों विधियों से YES वापस कर देते हैं तो आपके नियंत्रण/दृश्य में पहली प्रतिक्रियाकर्ता स्थिति होगी, जिसका अर्थ है कि यह सक्रिय नियंत्रण है। लेकिन, जैसा कि बताया गया है, एक NSTextField वास्तव में जब क्लिक क्षेत्र संपादक पहले प्रत्युत्तर स्थिति देता है, तो आप अपने NSTextField उपवर्ग में कुछ इस तरह करने की जरूरत है:

@implementation MCTextField 
- (BOOL)becomeFirstResponder 
{ 
    BOOL result = [super becomeFirstResponder]; 
    if(result) 
     [self performSelector:@selector(selectText:) withObject:self afterDelay:0]; 
    return result; 
} 
@end 

यह पहली -becomeFirstResponder की सुपर क्लास 'कार्यान्वयन कॉल जो करना होगा क्षेत्र संपादक के प्रबंधन का कड़ी मेहनत। इसके बाद -selectText: पर कॉल किया जाता है जो फ़ील्ड में सभी टेक्स्ट का चयन करता है, लेकिन यह 0 सेकंड की देरी के बाद ऐसा करता है, जो ईवेंट लूप के माध्यम से अगले रन तक देरी करेगा। इसका अर्थ यह है कि फ़ील्ड एडिटर पूरी तरह कॉन्फ़िगर किए जाने के बाद चयन होगा।

+0

बहुत बहुत शुक्रिया, यह खूबसूरती से काम किया और मुझे कुछ चीजें सीखने बना दिया। #import <कोको/Cocoa.h> @interface MCTextField: मैं कोड आपके द्वारा दी गई है, तो जैसे ज फ़ाइल से मीटर बना लिया, तो NSTextField {} @end और इंटरफ़ेस बिल्डर में मैं फ़ाइल -> कक्षा फ़ाइल पढ़ें, MCTextField.h का चयन किया, फिर मैंने अपने टेक्स्ट फ़ील्ड की कक्षा को MCTextField होने के लिए बदल दिया। –

+0

यह बहुत सामान्य "प्रोग्रामेटिक रूप से टेक्स्ट का चयन करें" के लिए समाधान भी है - उदाहरण के लिए, NSTextView में टेक्स्ट-सिलेक्ट रूटीन, कई मौकों पर सीधे डाले जाने पर सही ढंग से आग नहीं लगाते हैं, तो आपको उन्हें एक प्रदर्शन चयनकर्ता में रखना होगा : बाद में: 0 कॉल। Sigh – Adam

+1

यह 10.9 एसडीके में अच्छी तरह से काम नहीं करता है। जब मैं फ़ील्ड पर क्लिक करता हूं, तो मुझे एक झपकी वाली देखभाल मिलती है जब तक कि मैं 1 सेकंड की तरह बहुत देर से देरी नहीं करता। –

2

स्विफ्ट के साथ कुछ अपडेट:

import Cocoa 

class TextFieldSubclass: NSTextField { 
    override func mouseDown(theEvent: NSEvent) { 
     super.mouseDown(theEvent) 
     if let textEditor = currentEditor() { 
      textEditor.selectAll(self) 
     } 
    } 
} 

या सटीक चयन के लिए:

import Cocoa 

class TextFieldSubclass: NSTextField { 
    override func mouseDown(theEvent: NSEvent) { 
     super.mouseDown(theEvent) 
     if let textEditor = currentEditor() { 
      textEditor.selectedRange = NSMakeRange(location, length) 
     } 
    } 
} 

स्विफ्ट संस्करण, मेरे लिए काम करता है:

import Cocoa 

class TextFieldSubclass: NSTextField { 
    override func becomeFirstResponder() -> Bool { 
     let source = CGEventSourceCreate(CGEventSourceStateID.HIDSystemState) 
     let tapLocation = CGEventTapLocation.CGHIDEventTap 
     let cmdA = CGEventCreateKeyboardEvent(source, 0x00, true) 
     CGEventSetFlags(cmdA, CGEventFlags.MaskCommand) 
     CGEventPost(tapLocation, cmdA) 
     return true 
    } 
} 
4

@Rob से जवाब संभवतः एक बिंदु पर काम किया, लेकिन @Daniel संख्या के रूप में टेड, यह अब और काम नहीं करता है। ऐसा लगता है जैसे कोको माउस को ट्रैक करना चाहता है और एक क्लिक के जवाब में चयन खींचना चाहता है, और becomeFirstResponder के जवाब में टेक्स्ट का चयन करने का प्रयास करना इसके साथ अच्छा नहीं खेलता है।

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

@interface MyAutoselectTextField : NSTextField 
@end 

@implementation MyAutoselectTextField 
- (void)mouseDown:(NSEvent *)theEvent 
{ 
    [[self currentEditor] selectAll:nil]; 
} 
@end 

समय mouseDown: से बुलाया जाता है क्षेत्र संपादक पहले से ही स्थापित किया गया है: अधिक या परीक्षण और त्रुटि से कम, मैं एक समाधान है जो ओएस एक्स 10.10 पर काम करने लगता है मिल गया है ऊपर, शायद becomeFirstResponder के दुष्प्रभाव के रूप में। कॉलिंग selectAll: फिर फ़ील्ड एडिटर की सामग्री का चयन करता है। पर self पर कॉल करना इसके बजाय अच्छी तरह से काम नहीं करता है, संभवतया फ़ील्ड एडिटर स्थापित है।ध्यान दें कि mouseDown: का ओवरराइड कॉल super पर है; super एक ट्रैकिंग लूप चलाएगा जो चयन को खींच लेगा, और हम उस व्यवहार को नहीं चाहते हैं। ध्यान दें कि टेक्स्टफील्ड पहले प्रतिक्रियाकर्ता बनने के बाद यह mouseDown: ओवरराइड चयन को प्रभावित नहीं करता है, क्योंकि उस समय यह क्षेत्र संपादक का mouseDown: है जिसे कॉल किया जा रहा है।

मुझे नहीं पता कि ओएस एक्स संस्करणों की यह श्रृंखला किस प्रकार काम करती है; यदि आप परवाह करते हैं, तो आपको इसका परीक्षण करने की आवश्यकता होगी। दुर्भाग्यवश, NSTextField के साथ काम करना हमेशा थोड़ा नाजुक होता है क्योंकि फ़ील्ड संपादक काम करने का तरीका बहुत अजीब है और super में कार्यान्वयन विवरण पर निर्भर है।

1

मुझे कॉन्स्टेंटिन का समाधान पसंद है, लेकिन वह हर माउस पर नीचे चयन करेगा। यहाँ विभिन्नता मैं mouseDown विधि में चयन करने के लिए उपयोग कर रहा हूँ, लेकिन केवल अगर यह सिर्फ पहली प्रत्युत्तर बने:

class SelectingTextField: NSTextField { 

    var wantsSelectAll = false 

    override func becomeFirstResponder() -> Bool { 
     wantsSelectAll = true 

     return super.becomeFirstResponder() 
    } 

    override func mouseDown(with event: NSEvent) { 
     super.mouseDown(with: event) 

     if wantsSelectAll { 
      selectText(self) 
      wantsSelectAll = false 
     } 
    } 
} 
संबंधित मुद्दे