NSTextField नियंत्रण की एक जोड़ी को समन्वयित करना

मेरे पास दो एनएसटीक्स्टफाल्ड नियंत्रण वाली विंडो है जिसका मान एक दूसरे के साथ समन्वयित होना चाहिए। विशेष रूप से, एक चौड़ाई है और दूसरा लंबाई है और उनका अनुपात किसी दिए गए पहलू अनुपात के बराबर होना चाहिए। मैं चाहता हूं कि उपयोगकर्ता जो चाहें उसे सेट करने में सक्षम हो और अन्य अपडेट स्वचालित रूप से हो।

मेरा पहला दृष्टिकोण: मैंने खिड़की नियंत्रक होने के लिए दोनों नियंत्रणों में से प्रत्येक के लिए प्रतिनिधि सेट किया है। मैंने नियंत्रणTextDidEndEditing विधि को लागू किया। मैं प्रेषक की जांच करता हूं। यदि यह चौड़ाई क्षेत्र था, तो मैंने ऊंचाई क्षेत्र की गणना की और बाध्य संपत्ति (self.my_height = self.my_width/aspectRatio) के माध्यम से अपना मान अपडेट किया। इसी प्रकार, यदि यह ऊंचाई क्षेत्र था, (self.my_width = self.my_height * aspectRatio)।

लेकिन मैंने एक झटका मारा। मान लें कि पहलू अनुपात 1.5 था। उपयोगकर्ता चौड़ाई के क्षेत्र में 100 में प्रवेश करता है और फिर दूसरे फ़ील्ड पर चलता है। ऊंचाई फ़ील्ड 66 तक अपडेट (बेहतर या बदतर के लिए, मैंने हमेशा गोल करना चुना)। उपयोगकर्ता ऊंचाई क्षेत्र में क्लिक करता है, कोई बदलाव नहीं करता है और कहीं और क्लिक करता है। चौड़ाई क्षेत्र को 99 तक अपडेट किया गया है। उपयोगकर्ता अब उसके सिर को खरोंच कर रहा है।

मेरा परिष्करण मैंने विंडो नियंत्रक में नियंत्रणTextDidChange विधि भी लागू की। यह सब एक स्थिर (फ़ाइल स्कॉप्ड) बूल वैरिएबल (gTextFieldDidChange) को YES पर सेट करता है। अब, जब मैं controlTextDidEndEditing में प्रवेश करता हूं, तो मैं gTextFieldDidChange की स्थिति की जांच करता हूं। यदि नहीं, तो मैं तुरंत वापस आ गया। यदि हां, तो मैं gTextFieldDidChange को वापस NO पर साफ़ करता हूं और लंबाई/चौड़ाई अद्यतनों को संभालता हूं।

ऐसा लगता है कि मेरे लिए कोई समस्या नहीं है, लेकिन ऐसा लगता है कि यह "बैक-दरवाजा" है। क्या कोई क्लीनर/स्मार्ट दृष्टिकोण है जो मुझे याद आ रहा है?

किसी भी/सभी सुझावों के लिए धन्यवाद। माइक

0
ठीक है ... मैं कोड और यूआई दोनों में चौड़ाई/ऊंचाई गुणों को सेट/एक्सेस करने के लिए बाइंडिंग का उपयोग कर रहा हूं। जब उपयोगकर्ता वास्तव में दो NSTextField नियंत्रणों में से किसी एक में परिवर्तन करता है तो मैं केवल दो को "सिंक" करने के लिए समय कैसे प्राप्त करूं?
जोड़ा लेखक MikeMayer67, स्रोत
मुझे लगता है कि कोको बाइंडिंग बिल्कुल ठीक है की तलाश में है;)
जोड़ा लेखक HAS, स्रोत
@ माइकमेयर 68 मैंने केवल एक प्रतिनिधि विधि का उपयोग करके एक छोटा डेमो ऐप बनाया है और बाइंडिंग नहीं है क्योंकि यह एक बहुत ही मामूली मामला है। यदि आपके कोई प्रश्न हैं तो मुझे बताएं ;-)
जोड़ा लेखक HAS, स्रोत

2 उत्तर

मैंने वास्तव में अपनी समस्या के लिए एक बेहतर और सरल समाधान पाया जो मैंने शुरू में किया था और एचएएस द्वारा सुझाया गया था।

मैंने बस बाध्यकारी के तहत 'निरंतर अद्यतन मूल्य' बॉक्स को चेक किया। ऐसा करने का मतलब है कि नियंत्रण से कॉल करने से पहले बाध्य मान अद्यतन किया जाता है। टेक्स्टडिड चेंज।

अब मैं इसे टाइप कर सकता हूं क्योंकि इसे टाइप किया गया है और अब नियंत्रण के आमंत्रण तक निष्पादित करने की आवश्यकता नहीं है TextDidEndEditting।

0
जोड़ा

The following code does what you want using NSTextFieldDelegate> methods:

@interface HASMainViewController() 
@property (weak) IBOutlet NSTextField *widthTextField;
@property (weak) IBOutlet NSTextField *heightTextField;
@property (weak) IBOutlet NSTextField *ratioLabel;
@end

@implementation HASMainViewController

- (void)awakeFromNib {
    self.widthTextField.delegate = self;
    self.heightTextField.delegate = self;
    self.ratioLabel.stringValue = @"1.777777";//16:9 (1920 x 1080)
}

- (void)controlTextDidChange:(NSNotification *)obj {
    if (obj.object == self.widthTextField) {
       //If the width textfield gets changed we want to pass its value and -1 for calculating the height.
       //After that we set the height's text field to the calculated value.
        self.heightTextField.integerValue = [self calculateRatioComponentWithWidth:self.widthTextField.integerValue height:-1 ratio:self.ratioLabel.doubleValue];
    } else if (obj.object == self.heightTextField) {
       //If the width textfield gets changed we want to pass its value and -1 for calculating the height.
       //After that we set the height's text field to the calculated value.
        self.widthTextField.integerValue = [self calculateRatioComponentWithWidth:-1 height:self.heightTextField.integerValue ratio:self.ratioLabel.doubleValue];
    }
}

/**
 *  This method calculates the missing component (determined by "-1") for a given ratio.
 *
 *  @param width  An NSInteger representing the width. Pass -1 if this value should be calculated.
 *  @param height An NSInteger representing the height. Pass -1 if this value should be calculated.
 *  @param ratio  The ratio which needs to be kept.
 *
 *  @return An NSInteger which is depending on the what you passed as parameters the calculated width or height.
 *
 *  @discussion This method raises an HASInternalInconsistencyException exception if both width and height parameters are -1.
 *
 */
- (NSInteger)calculateRatioComponentWithWidth:(NSInteger)width height:(NSInteger)height ratio:(double)ratio {
    if (width == -1 && height == -1) [[NSException exceptionWithName:@"HASInternalInconsistencyException"
                                                              reason:@"Both width and height are -1 (to be calculated)."
                                                            userInfo:nil] raise];
   //Calculate new width
    if (width == -1) return (NSInteger)round(height * ratio);
   //Calculate new width
    else if (height == -1) return (NSInteger)round(width * 1/ratio);
   //Just to silence the compiler
    return 0;
}

@end

आप एक बिटबकेट रिपोजिटरी से एक छोटा नमूना ऐप क्लोन या डाउनलोड कर सकते हैं मैंने अभी आपके लिए बनाया है ;-)

0
जोड़ा
आह ... और मैं बहुत करीब था, लेकिन स्पष्ट याद किया। मैं दूसरे को सेट करने के लिए चौड़ाई (या ऊंचाई) संपत्ति के वर्तमान मूल्य का उपयोग करने का प्रयास कर रहा था। यह असफल रहा क्योंकि यह नियंत्रण से पहले अपडेट नहीं किया गया है टेक्स्टक्विड एंड एडिटिंग का आह्वान किया गया है। मुझे नियंत्रण से बाहर मूल्य को पकड़ने के लिए सोचने के लिए एक बोल्ट की तरह लग रहा है।
जोड़ा लेखक MikeMayer67, स्रोत
मुझे जवाब को ऊपर उठाने के लिए पर्याप्त प्रतिष्ठा नहीं है। लेकिन मैंने इसे स्वीकार कर लिया।
जोड़ा लेखक MikeMayer67, स्रोत
हाँ, तुम बहुत करीब थे!
जोड़ा लेखक HAS, स्रोत