2009-05-12 13 views
6

फिट करने के लिए दिए गए फ़ॉन्ट के साथ स्ट्रिंग लम्बाई मुझे टेक्स्ट को स्थानांतरित करने की आवश्यकता है जिसे उपयोगकर्ता ने एक बड़ी बहु-पंक्ति UITextView में एक छोटी (लेकिन अभी भी बहु-पंक्ति) UITextView * में प्रवेश किया है। यदि उपयोगकर्ता छोटे दृश्य में प्रदर्शित होने से अधिक टेक्स्ट दर्ज कर चुका है, तो मैं टेक्स्ट को छोटा करना चाहता हूं ताकि यह सभी (छिड़काव) टेक्स्ट दिखाई दे। (न तो बड़े UITextView और न ही छोटे को स्क्रॉल करना चाहिए।)UITextView

ऐसा करने का सबसे अच्छा तरीका क्या है?

मैं एक पाश का उपयोग कर सकते, एक चरित्र हर बार से स्ट्रिंग को छोटा करने, और उसके बाद का उपयोग NSString के sizeWithFont: constrainedToSize: lineBreakMode: ऊंचाई इस छोटे स्ट्रिंग की आवश्यकता होगी पता लगाने के लिए, और फिर तुलना कि ऊंचाई के खिलाफ मैं अपने छोटे में उपलब्ध है UITextView, स्ट्रिंग फिट होने पर लूप को समाप्त कर देगा - लेकिन यह धीमा और अजीब लगता है। इसके लिए अवश्य ही एक बेहतर तरीका होना चाहिए। '

मैं बस अपने प्रदर्शन को छोटा करने के लिए गंतव्य UITextView गंतव्य को बताना चाहता हूं क्योंकि यह स्क्रीन पर प्रदर्शित होता है, लेकिन मैं ऐसा करने का कोई तरीका नहीं ढूंढ पा रहा हूं।

* इस पर अधिक संदर्भ, एक टिप्पणी से मैं नीचे बनाया:

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

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

उत्तर

3

मैंने इसे ठीक से करने के लिए निम्नलिखित रिकर्सिव विधि और सार्वजनिक एपीआई लिखा था। बदसूरत फज कारक this question का विषय है।

#define kFudgeFactor 15.0 
#define kMaxFieldHeight 9999.0 

// recursive method called by the main API 
-(NSString*) sizeStringToFit:(NSString*)aString min:(int)aMin max:(int)aMax 
{ 
if ((aMax-aMin) <= 1) 
    { 
    NSString* subString = [aString substringToIndex:aMin]; 
    return subString; 
    } 

int mean = (aMin + aMax)/2; 
NSString* subString = [aString substringToIndex:mean]; 

CGSize tallerSize = CGSizeMake(self.frame.size.width-kFudgeFactor,kMaxFieldHeight); 
CGSize stringSize = [subString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap]; 

if (stringSize.height <= self.frame.size.height) 
    return [self sizeStringToFit:aString min:mean max:aMax]; // too small 
else  
     return [self sizeStringToFit:aString min:aMin max:mean];// too big 
} 

-(NSString*)sizeStringToFit:(NSString*)aString 
{ 

CGSize tallerSize = CGSizeMake(self.frame.size.width-kFudgeFactor,kMaxFieldHeight); 
CGSize stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap]; 

// if it fits, just return 
if (stringSize.height < self.frame.size.height) 
    return aString; 

// too big - call the recursive method to size it  
NSString* smallerString = [self sizeStringToFit:aString min:0 max:[aString length]]; 
return smallerString; 
} 
+0

यह कोड शानदार है, धन्यवाद, लेकिन मुझे दो स्थितियां मिली हैं जिनमें यह विफल रहता है: 1) यदि आपके पास स्ट्रिंग 2 पर बहुत सी जगहें हैं) "<" लाइन में "if (stringSize.height SpaceDog

1

मैं थोड़ा अलग दृष्टिकोण लेने और देखने का सुझाव दूंगा कि क्या आप छोटे UITextView के बजाय UILabel का उपयोग कर सकते हैं।

UILabels को उनके नंबरऑफलाइन संपत्ति के माध्यम से UITextView की तरह बहु-पंक्ति होने के लिए सेट किया जा सकता है।

उइलाबल्स में एक लाइन ब्रेकमोड संपत्ति भी है और मेरा मानना ​​है कि उस संपत्ति का डिफ़ॉल्ट मूल्य सटीक छंटनी प्रभाव करेगा जो आप खोज रहे हैं।

+1

लेकिन मुझे नहीं लगता कि UILabels संपादन योग्य हो सकता है, क्या वे कर सकते हैं? मैं चाहता हूं कि उपयोगकर्ता इन दोनों क्षेत्रों में टेक्स्ट दर्ज कर सके। (विशेष रूप से एक बार मैंने इसे छोटा कर दिया है - पाठ शायद समझ में नहीं आएगा।) –

+0

आप सही हैं UILabels संपादन योग्य नहीं हैं। मुझे लगता है कि तुमने मुझे अभी फेंक दिया है। सामान्य रूप से, मैं सोच रहा हूं कि आपके छोटे UITextView को संपादित करते समय उपयोगकर्ता अनुभव क्या होगा। क्या उपयोगकर्ता सभी टेक्स्ट या केवल उस हिस्से को संपादित कर सकता है जिसे छोटा नहीं किया गया है? यदि उपयोगकर्ता सभी पाठ को संपादित करने में सक्षम है, तो उपयोगकर्ता कैसे बता सकता है कि आपके संपादन सत्र समाप्त होने के बाद उनके संपादन को प्रभावी कर दिया गया है? इन कारणों से, मैं छोटे दृश्य को पाठ के केवल पढ़ने के सारांश के रूप में रखने पर विचार कर सकता हूं। –

+0

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

1

मुझे लगता है कि जोनाथन UILabel के बारे में कुछ करने के बारे में था ...

तो, उपयोगकर्ता संपादन समाप्त कर ले UITextView, आप पाठ की स्ट्रिंग मिलता है और यह UILabel को गुजरती हैं। आप UITextView के अल्फा को 0 पर बदलते हैं और/या इसे पर्यवेक्षण से हटा दें। संभवतः एक ivar में untruncated पूर्ण पाठ स्टोर।

उइलाबेल "संपादन योग्य" नहीं हैं, हालांकि आप UILabel (या इसके पर्यवेक्षण) के साथ एक स्पर्श का पता लगा सकते हैं। जब आप UILabel पर स्पर्श का पता लगाते हैं, तो आप बस छुपा UITextView को पुनर्स्थापित करते हैं और सहेजी गई स्ट्रिंग को पुनर्स्थापित करते हैं।

कभी-कभी एसडीके दर्द होता है, लेकिन यह लगभग हमेशा जीत जीतता है। कई बार, यूआईकिट सम्मेलनों में अपने डिजाइन को समायोजित करना बेहतर होता है

2

यह वास्तव में एक फिक्स नहीं है लेकिन यह गणना के लिए एक अच्छा प्रारंभिक पोइंग प्रदान करता है।

यदि आप एनएसएसटींगिंग sizeWithFont: constrainedToSize: lineBreakMode: का उपयोग करते हैं तो आपको अपने टेक्स्ट के लिए लंबवत ऊंचाई मिलती है। यदि आप इसे अपने फ़ॉन्ट की अग्रणी ऊंचाई से विभाजित करते हैं, तो आपको पूरी स्ट्रिंग में लाइनों की संख्या मिलती है। उस संख्या से विभाजित [एनएसएसटींग गिनती] आपको प्रति पंक्ति वर्णों की संख्या के लिए अनुमानित करता है।इसका मतलब यह है स्ट्रिंग homogeneuous है और गलत हो सकता है अगर किसी प्रकार (उदाहरण के लिए) 'iiiiiiiiiii ... mmmmmmmmm "के रूप में oposed" ... "।

लिए प्रासंगिक फ़ॉन्ट के leading ऊंचाई से

तुम भी आप बाउंडिंग विभाजित कर सकते हैं बॉक्स लाइनों अपने सीमांकन बॉक्स के भीतर फिट कि की संख्या मिलता है।

लाइनों की संख्या से प्रति पंक्ति वर्ण गुणा आप पाठ कि फिट बैठता है खोजने के लिए प्रारंभिक बिंदु देता है।

आप तक यह प्रतिशत में त्रुटि के लिए मार्जिन की गणना कर सकते उन 'iiiiii ...' और "MMMMMM ... '" स्ट्रिंग्स के लिए समान गणना कर रहे हैं।

+0

सहमत हैं, यह एक अच्छा दृष्टिकोण है, और इसलिए ऊपर की विधि का उपयोग कर स्ट्रिंग लम्बाई पर बाइनरी काट कर रहा है। मुझे अभी भी उम्मीद है कि एक बेहतर तरीका है, लेकिन मुझे अब महसूस हो रहा है कि वहां नहीं है। –

+0

समाधान कूरियर है। फिक्स्ड चौड़ाई फोंट, कोई गणित ... –

+0

@ ट्रिस्टन, केवल तभी जब आप लपेटते समय सफेद जगह को अनदेखा करते हैं। यद्यपि यह एक आसान समस्या होगी। –