How to add line numbers to a UITextView?

前端 未结 2 1227
再見小時候
再見小時候 2020-12-25 15:08

I want to add line numbers to my UITextView.
Do I have to write my own UI-Element, or is there an other solution?

相关标签:
2条回答
  • 2020-12-25 15:35

    There's nothing built-in for this. You'll have to do it yourself.

    0 讨论(0)
  • 2020-12-25 15:38

    I accomplished this by subclassing UIView and overriding the drawRect: method like so:

    #define TXT_VIEW_INSETS 8.0 // The default insets for a UITextView is 8.0 on all sides
    
    @implementation NumberedTextView
    
    @synthesize lineNumbers;
    @synthesize delegate;
    
    - (id)initWithFrame:(CGRect)frame {
        if ((self = [super initWithFrame:frame])) {
            [self setContentMode:UIViewContentModeRedraw];
    
            internalScrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
            [internalScrollView       setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
            [internalScrollView        setBackgroundColor:[UIColor clearColor]];
            [internalScrollView          setClipsToBounds:YES];
            [internalScrollView           setScrollsToTop:YES];
            [internalScrollView            setContentSize:self.bounds.size];
            [internalScrollView            setContentMode:UIViewContentModeLeft];
            [internalScrollView               setDelegate:self];
            [internalScrollView                setBounces:NO];
    
            internalTextView = [[UITextView alloc] initWithFrame:self.bounds];
            [internalTextView  setAutocapitalizationType:UITextAutocapitalizationTypeNone];
            [internalTextView      setAutocorrectionType:UITextAutocorrectionTypeNo];
            [internalTextView       setSpellCheckingType:UITextSpellCheckingTypeNo];
            [internalTextView        setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
            [internalTextView         setBackgroundColor:[UIColor clearColor]];
            [internalTextView           setClipsToBounds:YES];
            [internalTextView            setScrollsToTop:NO];
            [internalTextView             setContentMode:UIViewContentModeLeft];
            [internalTextView                setDelegate:self];
            [internalTextView                 setBounces:NO];
    
            [internalScrollView addSubview:internalTextView];
            [self addSubview:internalScrollView];
        }
        return self;
    }
    
    - (void)drawRect:(CGRect)rect {
        if (self.lineNumbers) {
            [[internalTextView textColor] set];
            CGFloat xOrigin, yOrigin, width/*, height*/;
            uint numberOfLines = (internalTextView.contentSize.height + internalScrollView.contentSize.height) / internalTextView.font.lineHeight;
            for (uint x = 0; x < numberOfLines; ++x) {
                NSString *lineNum = [NSString stringWithFormat:@"%d:", x];
    
                xOrigin = CGRectGetMinX(self.bounds);
    
                yOrigin = ((internalTextView.font.pointSize + abs(internalTextView.font.descender)) * x) + TXT_VIEW_INSETS - internalScrollView.contentOffset.y;
    
                width = [lineNum sizeWithFont:internalTextView.font].width;
    //            height = internalTextView.font.lineHeight;
    
                [lineNum drawAtPoint:CGPointMake(xOrigin, yOrigin) withFont:internalTextView.font];
            }
    
            CGRect tvFrame = [internalTextView frame];
            tvFrame.size.width = CGRectGetWidth(internalScrollView.bounds) - width;
            tvFrame.size.height = MAX(internalTextView.contentSize.height, CGRectGetHeight(internalScrollView.bounds));
            tvFrame.origin.x = width;
            [internalTextView setFrame:tvFrame];
            tvFrame.size.height -= TXT_VIEW_INSETS; // This fixed a weird content size problem that I've forgotten the specifics of.
            [internalScrollView setContentSize:tvFrame.size];
        }
    }
    
    #pragma mark - UITextView Delegate
    
    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
        [self setNeedsDisplay];
        return YES;
    }
    
    - (void)textViewDidChange:(UITextView *)textView {
        [self setNeedsDisplay];
    }
    
    - (void)textViewDidChangeSelection:(UITextView *)textView {
        [self setNeedsDisplay];
    }
    
    #pragma mark - UIScrollView Delegate
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        [self setNeedsDisplay];
    }
    
    0 讨论(0)
提交回复
热议问题