1
votes

I must be doing something wrong here: textview with "double vision"

My Cocoa app has a scrollview around a custom view which in turn has a textview. I only expect to see one "This is a " string but there the extra one up in the corner. I have reduced the code to something very minimal and still do not understand what my error is, so here I am fishing for a clue.

The view controller for the custom view follows, but for simplicity here is a link to the project.

#import "TTTSimpleCtrlView.h"

@interface TTTSimpleCtrlView ()

@property (strong,nonatomic) NSTextView *tv1;
@property (strong,nonatomic) NSTextStorage *ts;

@end

@implementation TTTSimpleCtrlView

- (void) awakeFromNib {
    NSFont *font = [NSFont fontWithName:@"Courier New Bold" size:20.0f];
    NSMutableParagraphStyle *styleModel = [[NSParagraphStyle  defaultParagraphStyle] mutableCopy];
    [styleModel setLineHeightMultiple:1.0];
    //    [styleModel setLineSpacing:fontRect.size.height * 2];
    NSDictionary *textAttrs = [NSDictionary dictionaryWithObjectsAndKeys: font, NSFontAttributeName,
                                     [NSColor blackColor] ,NSForegroundColorAttributeName,
                                     [NSColor whiteColor], NSBackgroundColorAttributeName,
                                     styleModel, NSParagraphStyleAttributeName,
                                     nil];
    NSString *pilcrowStr = @"This is a test.";
    NSAttributedString *s = [[NSAttributedString alloc] initWithString:pilcrowStr attributes:textAttrs];
    NSRect rect = [s boundingRectWithSize:NSMakeSize(INFINITY,INFINITY)options:0];
    NSLayoutManager *lm = [[NSLayoutManager alloc] init];
    NSTextContainer *tc = [NSTextContainer new];

    [tc setContainerSize:s.size];
    [lm addTextContainer:tc];

    _ts = [[NSTextStorage alloc] init];
    [_ts setAttributedString:s];

    [_ts addLayoutManager:lm];
    [lm replaceTextStorage:_ts];

    rect.origin.x = 10;
    rect.origin.y = rect.size.height;
    NSTextView *v = [[NSTextView alloc] initWithFrame:rect textContainer:tc];
    [v setDrawsBackground:YES];
    [self addSubview:v];
}

- (BOOL) isFlipped {
    return YES;
}

- (void)drawRect:(NSRect)rect
{
    NSLog(@"drawRect & %lu subviews",self.subviews.count);
    for (NSTextView *v in self.subviews) {
        if(CGRectIntersectsRect(v.frame, rect) || CGRectContainsRect(rect, v.frame)) {
            [v drawRect:rect];
            NSLog(@"frame = %@",NSStringFromRect(v.frame));
        }
    }
    [super drawRect:rect];
}
1
So, I have managed to work around this problem with a completely different approach. And as an added bonus this post earned me a 'tumbleweed' badge. Seriously, though I wish somebody would take mercy.... - zer0gravitas

1 Answers

1
votes

You are calling:

[super drawRect:rect];

and you are drawing the text yourself in your draw function. In effect you are drawing the text and cocoa is drawing the text for you as well. So don't call super.