how to toggle rich text formatting in NSTextView programmatically in cocoa

梦想的初衷 提交于 2021-01-27 11:11:58

问题


I want to toggle rich text formatting in NSTextView. I have tried following:

[contentView setRichText:NO];
[contentView setImportsGraphics:NO];

but, that didn't changed the NSTextView content and still allowing to do the text formatting.

Please let me know the simple way to toggle/switch rich text formatting in NSTextView just like TextEdit.

I already check the "TextEdit" sample project, but it seems to be very hard to find the usable code from it.

Thanks


回答1:


Found some help from following link.

click here to see solution

Based on solution given in above link, i have created category for my view controller as follows:

#define TabWidth @"TabWidth"

@interface MyViewController (Helper)

- (NSDictionary *)defaultTextAttributes:(BOOL)forRichText;
- (void)removeAttachments;
- (void)setRichText:(BOOL)flag;

@end

@implementation MyViewController (Helper)

- (NSDictionary *)defaultTextAttributes:(BOOL)forRichText {
    static NSParagraphStyle *defaultRichParaStyle = nil;
    NSMutableDictionary *textAttributes = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease];
    if (forRichText) {
        [textAttributes setObject:[NSFont userFontOfSize:0.0] forKey:NSFontAttributeName];
        if (defaultRichParaStyle == nil) {  // We do this once...
            NSInteger cnt;
            NSString *measurementUnits = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleMeasurementUnits"];
            CGFloat tabInterval = ([@"Centimeters" isEqual:measurementUnits]) ? (72.0 / 2.54) : (72.0 / 2.0);  // Every cm or half inch
            NSMutableParagraphStyle *paraStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
            [paraStyle setTabStops:[NSArray array]];    // This first clears all tab stops
            for (cnt = 0; cnt < 12; cnt++) {    // Add 12 tab stops, at desired intervals...
                NSTextTab *tabStop = [[NSTextTab alloc] initWithType:NSLeftTabStopType location:tabInterval * (cnt + 1)];
                [paraStyle addTabStop:tabStop];
                [tabStop release];
            }
            defaultRichParaStyle = [paraStyle copy];
        }
        [textAttributes setObject:defaultRichParaStyle forKey:NSParagraphStyleAttributeName];
    } else {
        NSFont *plainFont = [NSFont userFixedPitchFontOfSize:0.0];
        NSInteger tabWidth = [[NSUserDefaults standardUserDefaults] integerForKey:TabWidth];
        CGFloat charWidth = [@" " sizeWithAttributes:[NSDictionary dictionaryWithObject:plainFont forKey:NSFontAttributeName]].width;
        if (charWidth == 0) charWidth = [[plainFont screenFontWithRenderingMode:NSFontDefaultRenderingMode] maximumAdvancement].width;

        // Now use a default paragraph style, but with the tab width adjusted
        NSMutableParagraphStyle *mStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
        [mStyle setTabStops:[NSArray array]];
        [mStyle setDefaultTabInterval:(charWidth * tabWidth)];
        [textAttributes setObject:[[mStyle copy] autorelease] forKey:NSParagraphStyleAttributeName];

        // Also set the font
        [textAttributes setObject:plainFont forKey:NSFontAttributeName];
    }
    return textAttributes;
}

/* Used when converting to plain text
 */
- (void)removeAttachments {
    NSTextStorage *attrString = [contentView textStorage];
    NSUInteger loc = 0;
    NSUInteger end = [attrString length];
    [attrString beginEditing];
    while (loc < end) { /* Run through the string in terms of attachment runs */
        NSRange attachmentRange;    /* Attachment attribute run */
        NSTextAttachment *attachment = [attrString attribute:NSAttachmentAttributeName atIndex:loc longestEffectiveRange:&attachmentRange inRange:NSMakeRange(loc, end-loc)];
        if (attachment) {   /* If there is an attachment and it is on an attachment character, remove the character */
            unichar ch = [[attrString string] characterAtIndex:loc];
            if (ch == NSAttachmentCharacter) {
                if ([contentView shouldChangeTextInRange:NSMakeRange(loc, 1) replacementString:@""]) {
                    [attrString replaceCharactersInRange:NSMakeRange(loc, 1) withString:@""];
                    [contentView didChangeText];
                }
                end = [attrString length];  /* New length */
            }
            else loc++; /* Just skip over the current character... */
        }
        else loc = NSMaxRange(attachmentRange);
    }
    [attrString endEditing];
}

- (void)setRichText:(BOOL)flag {
    NSDictionary *textAttributes;

    BOOL isRichText = flag;

    if (!isRichText) [self removeAttachments];

    [contentView setRichText:isRichText];
    [contentView setUsesRuler:isRichText];    /* If NO, this correctly gets rid
                                               of the ruler if it was up */
    if (isRichText && NO)
        [contentView setRulerVisible:YES];    /* Show ruler if rich, and desired */
    [contentView setImportsGraphics:isRichText];

    textAttributes = [self defaultTextAttributes:isRichText];

    if ([[contentView textStorage] length]) {
        [[contentView textStorage] setAttributes:textAttributes range: NSMakeRange(0,[[contentView textStorage] length])];
    }
    [contentView setTypingAttributes:textAttributes];
}

@end

Where contentView is IBOutlet of NSTextView. Hope this will help someone or let me know if someone has shorter method.

Thanks



来源:https://stackoverflow.com/questions/6519179/how-to-toggle-rich-text-formatting-in-nstextview-programmatically-in-cocoa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!