2013-01-01 38 views
11

प्रसंग:एनएसटीएक्स्टव्यू में समृद्ध टेक्स्ट को समान रूप से कैसे स्केल करें?

मैं एक सामान्य दस्तावेज़ आधारित कोको मैक ओएस एक्स आवेदन जो रिच टेक्स्ट इनपुट के लिए एक NSTextView का उपयोग करता है। उपयोगकर्ता NSTextView में टेक्स्ट परिवार, बिंदु आकार और टेक्स्ट के रंगों को संपादित कर सकता है।

बेस एसडीके: 10.7
तैनाती लक्ष्य: 10,6


प्रश्न:

मैं प्रोग्राम के रूप में पूरे यूआई के जूमिंग (NSTextView सहित), जबकि उपयोगकर्ता संपादित कर रहा है लागू करने के लिए चाहते हैं पाठ। NSTextView के फ्रेम को स्केलिंग कोई समस्या नहीं है। लेकिन मुझे नहीं पता कि दृश्य के अंदर संपादन योग्य पाठ को कैसे स्केल करना है जिसमें पाठ के पूरे भाग के विभिन्न उप-वर्गों में कई अलग-अलग बिंदु आकार हो सकते हैं।

NSTextView में प्रदर्शित समृद्ध पाठ में एक समान पैमाने पर कारक कैसे लागू कर सकता हूं?

यह "रिच टेक्स्ट", ऐसा है कि उपयोगकर्ता के फ़ॉन्ट परिवार, रंग और विशेष रूप से बिंदु आकार संरक्षित कर रहे हैं (जो पाठ के रन के विभिन्न बिंदुओं पर अलग हो सकता है), लेकिन समान रूप से बढ़ाया/अपेक्षाकृत के साथ अच्छी तरह खेलना चाहिए ।

क्या यह संभव है कि मेरा बेस एसडीके और परिनियोजन लक्ष्य दिया जाए? क्या यह एक नए बेस एसडीके या परिनियोजन लक्ष्य के साथ संभव है?

+2

के लिए काम करता है क्या यह संभव है आप 10.8 अप की आवश्यकता होती है और और 10.8 के अंतर्निहित पाठ जूम का उपयोग कर सकता है? यदि आपको 10.8 की आवश्यकता हो सकती है और पाठ को ज़ूम किए गए क्षेत्र में लपेटना नहीं है, तो यह एक रास्ता आगे हो सकता है। TextEdit के व्यू> ज़ूम ... मेनू आइटम देखें। –

उत्तर

10

यदि उद्देश्य दृश्य को स्केल करना है (और वास्तव में स्ट्रिंग में विशेषताओं को नहीं बदलना है), तो मैं स्केल यूनीट स्क्वायरटॉइस का उपयोग करने का सुझाव दूंगा: विधि: उचित स्क्रॉल बार व्यवहार के लिए स्केलिंगस्क्रोलव्यू (टेक्स्ट एडिट नमूना कोड के साथ उपलब्ध) के साथ।

ScalingScrollView से कोर टुकड़ा है:

- (void) scaleChanged:(CGFloat)oldScale newScale:(CGFloat)newScale 
{ 
    NSInteger  percent = lroundf(newScale * 100); 

    CGFloat scaler = newScale/oldScale; 
    [textView scaleUnitSquareToSize:NSMakeSize(scaler, scaler)]; 

    NSLayoutManager* lm = [textView layoutManager]; 
    NSTextContainer* tc = [textView textContainer]; 
    [lm ensureLayoutForTextContainer:tc]; 
} 

scaleUnitSquareToSize: विधि अपनी वर्तमान स्थिति के सापेक्ष मापता है, तो आप:

- (void)setScaleFactor:(CGFloat)newScaleFactor adjustPopup:(BOOL)flag 
{ 
CGFloat oldScaleFactor = scaleFactor; 
    if (scaleFactor != newScaleFactor) 
    { 
     NSSize curDocFrameSize, newDocBoundsSize; 
     NSView *clipView = [[self documentView] superview]; 

     scaleFactor = newScaleFactor; 

     // Get the frame. The frame must stay the same. 
     curDocFrameSize = [clipView frame].size; 

     // The new bounds will be frame divided by scale factor 
     newDocBoundsSize.width = curDocFrameSize.width/scaleFactor; 
     newDocBoundsSize.height = curDocFrameSize.height/scaleFactor; 
    } 
    scaleFactor = newScaleFactor; 
    [scale_delegate scaleChanged:oldScaleFactor newScale:newScaleFactor]; 
} 

scale_delegate आपका प्रतिनिधि है कि आपके NSTextView वस्तु समायोजित कर सकते हैं है अपने पैमाने के कारक का ट्रैक रखें और फिर अपने पूर्ण पैमाने अनुरोध (200%) को एक सापेक्ष पैमाने अनुरोध में परिवर्तित करें।

+0

धन्यवाद, यहां बहुत अच्छी जानकारी है! पूरा होने पर मैं अपनी प्रतिक्रिया खोदूँगा और अपडेट करूंगा। –

+0

अद्यतन: यह वास्तव में मुझे आवश्यक जानकारी थी। मैं जो चाहता था उसे प्राप्त करने के लिए '-scaleUnitSquareToSize:' विधि का उपयोग करने में सक्षम था। धन्यवाद मार्क! –

1

ओपी यहां।

मुझे एक समाधान मिला जो कि काम करता है और इसे लागू करने में बहुत मुश्किल नहीं है। मुझे यकीन नहीं है कि यह सबसे अच्छा/आदर्श समाधान है हालांकि। मैं अभी भी अन्य समाधान खोजने में रुचि रखता हूं।

मैन्युअल स्रोत के रूप में भंडारण से पहले फ़ॉन्ट बिंदु आकार और लाइन ऊंचाई अनेक प्रदर्शन से पहले NSAttributedString पाठ स्रोत के गुण, और फिर संयुक्त राष्ट्र पैमाने पर प्रदर्शित पाठ पैमाने: लेकिन यहाँ एक तरीका है।

इस समाधान के साथ समस्या यह है कि स्केल किए जाने पर, सिस्टम फ़ॉन्ट पैनल संपादित करते समय चयनित पाठ के वास्तविक स्केल किए गए प्रदर्शन बिंदु आकार (वास्तविक "स्रोत बिंदु आकार के बजाय) दिखाएगा। यह वांछनीय नहीं है।


यहाँ इस बात का मेरे कार्यान्वयन है:

- (void)scaleAttributedString:(NSMutableAttributedString *)str by:(CGFloat)scale { 
    if (1.0 == scale) return; 

    NSRange r = NSMakeRange(0, [str length]); 
    [str enumerateAttribute:NSFontAttributeName inRange:r options:0 usingBlock:^(NSFont *oldFont, NSRange range, BOOL *stop) { 
     NSFont *newFont = [NSFont fontWithName:[oldFont familyName] size:[oldFont pointSize] * scale]; 

     NSParagraphStyle *oldParaStyle = [str attribute:NSParagraphStyleAttributeName atIndex:range.location effectiveRange:NULL]; 
     NSMutableParagraphStyle *newParaStyle = [[oldParaStyle mutableCopy] autorelease]; 

     CGFloat oldLineHeight = [oldParaStyle lineHeightMultiple]; 
     CGFloat newLineHeight = scale * oldLineHeight; 
     [newParaStyle setLineHeightMultiple:newLineHeight]; 

     id newAttrs = @{ 
      NSParagraphStyleAttributeName: newParaStyle, 
      NSFontAttributeName: newFont, 
     }; 
     [str addAttributes:newAttrs range:range]; 
    }];  
} 

इस प्रदर्शन से पहले स्रोत पाठ स्केलिंग की आवश्यकता है:

// scale text 
CGFloat scale = getCurrentScaleFactor(); 
[self scaleAttributedString:str by:scale]; 

और फिर रिवर्स स्केलिंग स्रोत के रूप में भंडारण से पहले प्रदर्शित पाठ:

// un-scale text 
CGFloat scale = 1.0/getCurrentScaleFactor(); 
[self scaleAttributedString:str by:scale]; 
5

दोनों आईओएस और मैक ओएस

@implementation NSAttributedString (Scale) 

- (NSAttributedString *)attributedStringWithScale:(double)scale 
{ 
    if(scale == 1.0) 
    { 
     return self; 
    } 

    NSMutableAttributedString *copy = [self mutableCopy]; 
    [copy beginEditing]; 

    NSRange fullRange = NSMakeRange(0, copy.length); 

    [self enumerateAttribute:NSFontAttributeName inRange:fullRange options:0 usingBlock:^(UIFont *oldFont, NSRange range, BOOL *stop) { 
     double currentFontSize = oldFont.pointSize; 
     double newFontSize = currentFontSize * scale; 

     // don't trust -[UIFont fontWithSize:] 
     UIFont *scaledFont = [UIFont fontWithName:oldFont.fontName size:newFontSize]; 

     [copy removeAttribute:NSFontAttributeName range:range]; 
     [copy addAttribute:NSFontAttributeName value:scaledFont range:range]; 
    }]; 

    [self enumerateAttribute:NSParagraphStyleAttributeName inRange:fullRange options:0 usingBlock:^(NSParagraphStyle *oldParagraphStyle, NSRange range, BOOL *stop) { 

     NSMutableParagraphStyle *newParagraphStyle = [oldParagraphStyle mutableCopy]; 
     newParagraphStyle.lineSpacing *= scale; 
     newParagraphStyle.paragraphSpacing *= scale; 
     newParagraphStyle.firstLineHeadIndent *= scale; 
     newParagraphStyle.headIndent *= scale; 
     newParagraphStyle.tailIndent *= scale; 
     newParagraphStyle.minimumLineHeight *= scale; 
     newParagraphStyle.maximumLineHeight *= scale; 
     newParagraphStyle.paragraphSpacing *= scale; 
     newParagraphStyle.paragraphSpacingBefore *= scale; 

     [copy removeAttribute:NSParagraphStyleAttributeName range:range]; 
     [copy addAttribute:NSParagraphStyleAttributeName value:newParagraphStyle range:range]; 
    }]; 

    [copy endEditing]; 
    return copy; 
} 

@end