2009-02-09 11 views
5

पर बाध्यकारी मैं पूर्णांक उपयोगकर्ता इनपुट के लिए एक NSTextField का उपयोग करने का प्रयास कर रहा हूं। टेक्स्ट फ़ील्ड एनएसएनंबर संपत्ति से जुड़ा हुआ है और सेटर विधि में मैं इनपुट मान को साफ़ करता हूं (सुनिश्चित करें कि यह एक int है) और यदि आवश्यक हो तो संपत्ति सेट करें। मैं willChangeValueForKey भेजता हूं: और कियाChangeValueForKey: लेकिन यूआई नए मानों को अपडेट नहीं करता है जबकि वह टेक्स्ट फ़ील्ड अभी भी सक्रिय है।NSTextField को NSNumber

इसलिए उदाहरण के लिए मैं "12abc" पाठ फ़ील्ड सेटर विधि को साफ करने के लिए "12" में टाइप कर सकते हैं, लेकिन पाठ क्षेत्र अभी भी "12abc" को दर्शाता है।

मेरे पास इंटरफ़ेस बिल्डर में "निरंतर अद्यतन मूल्य" चेक किया गया है।

(मैं भी देखा है कि सेटर विधि एक NSString है, न कि NSNumber प्राप्त करता है। सामान्य? कि है)

एक NSNumber के लिए एक NSTextField ऊपर hooking करने का सही तरीका क्या है? संपत्ति के लिए सेटटर विधि कैसी दिखती है? गैर-संख्यात्मक मानों को टेक्स्ट फ़ील्ड में दिखने से कैसे रोकें?

उत्तर

0

मैं तुम्हें अपने NSTextField के लिए एक नंबर फ़ॉर्मेटर स्थापित करने के लिए की जरूरत है। Applying Formatters:

जाओ एप्पल की वेबसाइट पर formatters के बारे में पढ़ा है।

+0

मैं के रूप में डॉक में आप ने कहा में सुझाव दिया, लेकिन कुछ नहीं होता पाठ क्षेत्र पर छोड़ने के द्वारा एक नंबर फ़ॉर्मेटर गयी। मैं अभी भी गैर संख्यात्मक वर्ण टाइप कर सकता हूं। क्या मुझे फॉर्मेटर को टेक्स्ट फ़ील्ड से जोड़ने के अलावा कुछ और करने की ज़रूरत है? – lajos

1

बेन की तरह उल्लेख किया गया है, ऐसा करने का एक तरीका है अपने टेक्स्टफील्ड में एक NSNumberFormatter संलग्न करना, जो इंटरफ़ेस बिल्डर में स्थापित करने के लिए बहुत छोटा है और संभवतः बस वर्क ™ होगा।

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

एक और तरीका एनएसएनयूएलयू ट्रांसफॉर्मर सबक्लास को एनएसएनबर्स और पीठ में स्ट्रिंग को पार्स करने के लिए बनाना और पंजीकरण करना है, लेकिन मैं पहले एनएसएनंबरफॉर्मेटर का उपयोग करने की कोशिश करता हूं क्योंकि यह स्पष्ट रूप से कक्षा है जिसे इस सटीक उद्देश्य के लिए डिजाइन किया गया है।

More about value transformers

10

I send the willChangeValueForKey: and didChangeValueForKey:, but the UI doesn't update to the new values while that text field is still active.

वहाँ बहुत कुछ कारणों से उन संदेश भेजने के लिए कर रहे हैं। आम तौर पर, आप एक्सेसर्स (या बेहतर, अभी तक गुणों) को लागू करने और उपयोग करके एक ही काम बेहतर और अधिक साफ कर सकते हैं। जब आप ऐसा करते हैं तो केवीओ आपके लिए अधिसूचनाएं भेजेगा।

आपके मामले में, आप या तो अस्वीकार या फर्जी आदानों को फिल्टर ("12abc" की तरह) करना चाहते हैं। इस कार्य के लिए सही उपकरण कुंजी-मान सत्यापन है।

इस सक्षम करने के लिए आईबी में बंधन पर "पुष्टि तुरंत" बॉक्स को चेक करें, और एक सत्यापन विधि को लागू।

छनन:

- (BOOL) validateMyValue:(inout NSString **)newValue error:(out NSError **)outError { 
    NSString *salvagedNumericPart; 
    //Determine whether you can salvage a numeric part from the string; in your example, that would be “12”, chopping off the “abc”. 
    *newValue = salvagedNumericPart; //@"12" 
    return (salvagedNumericPart != nil); 
} 

को अस्वीकार करते हुए:

- (BOOL) validateMyValue:(inout NSString **)newValue error:(out NSError **)outError { 
    BOOL isEntirelyNumeric; 
    //Determine whether the whole string (perhaps after stripping whitespace) is a number. If not, reject it outright. 
    if (isEntirelyNumeric) { 
     //The input was @"12", or it was @" 12 " or something and you stripped the whitespace from it, so *newValue is @"12". 
     return YES; 
    } else { 
     if (outError) { 
      *outError = [NSError errorWithDomain:NSCocoaErrorDomain code: NSKeyValueValidationError userInfo:nil]; 
     } 
     //Note: No need to set *newValue here. 
     return NO; 
    } 
} 

(I've also noticed that the setter method receives an NSString, not an NSNumber. Is that normal?)

हाँ, जब तक आप एक मूल्य के ट्रांसफार्मर कि संख्या में तार बदल देती है का उपयोग करें, एक नंबर फ़ॉर्मेटर formatter आउटलेट से, कनेक्ट या स्थानापन्न आपकी सत्यापन विधि में एनएसएसटींग के लिए एक NSNumber।

+0

सत्यापन तरीकों में से एक हस्ताक्षर है लगता है: - (bool) validateNewValue: (आईडी *) ioValue त्रुटि: (NSError **) outError; लेकिन अगर मैं सही हस्ताक्षर के साथ एक विधि को लागू करता हूं और मान देता हूं या मान को सही करता हूं, तो टेक्स्ट फ़ील्ड अभी भी गैर संख्यात्मक वर्ण दिखाता है। – lajos

+0

विधि हस्ताक्षर के बारे में नोट के लिए धन्यवाद- मैंने अपना जवाब सही कर दिया है। क्या आपने "तुरंत मान्य" बॉक्स को चेक किया था? मुझे यकीन नहीं है कि कोड को देखे बिना समस्या क्या हो सकती है। –

+0

मैं एक परीक्षण परियोजना यहां पोस्ट: www.codza.com/files/numericFieldTest.zip सत्यापित करें विधि सही ढंग से वापस आती है हाँ या नहीं (लॉग देखें), लेकिन पाठ क्षेत्र अभी भी अल्फा वर्ण को दर्शाता है। इसे देखने के लिए बहुत बहुत धन्यवाद। आप www.codza.com/contact पर मुझसे संपर्क कर सकते हैं और मैं यहां टिप्पणियों की भी जांच करूंगा। – lajos

2

पीटर Hosey उत्तम जवाब पर एक महत्वपूर्ण टिप्पणी है कि मैं शीर्ष स्तर पर लाने के लिए चाहते हैं (क्योंकि मैं यह मेरी पहली पास पर याद किया) नहीं है।

यदि आप प्रत्येक बार एक फ़ील्ड दर्ज करते हैं, तो प्रत्येक बार जब कोई अक्षर दर्ज किया जाता है, तो आप NSTextField को सत्यापित/संशोधित करना चाहते हैं, तो आप केवल बाइंडिंग से जो चाहते हैं उसे प्राप्त नहीं कर सकते हैं। आपको टेक्स्ट फ़ील्ड में एक प्रतिनिधि को असाइन करने की आवश्यकता है, और फिर प्रतिनिधि में - (void)controlTextDidChange:(NSNotification *)aNotification लागू करें। टेक्स्ट बदलते समय हर बार इसे कॉल किया जाएगा। यदि आप चाहते हैं, तो आप मूल्य सत्यापनकर्ता को controlTextDidChange पर कॉल कर सकते हैं।

उदाहरण के लिए:

- (void)controlTextDidChange:(NSNotification *)aNotification 
{ 
    NSError *outError; 
    NSControl *textField = [aNotification object]; 
    NSString *myText = [textField stringValue]; 

    // myObject is the model object that owns the text in question 
    // the validator can modify myText by reference 
    [myObject validateValue:&myText error:&outError]]; 

    // update the NSNextField with the validated text 
    [postingObject setStringValue:myText]; 
} 
संबंधित मुद्दे