iphone - 如何将行号添加到 UITextView?

标签 iphone objective-c ipad

我想在我的 UITextView 中添加行号。
我必须编写自己的 UI 元素,还是有其他解决方案?

最佳答案

我通过子类化 UIView 并覆盖 drawRect: 方法来完成此操作,如下所示:

#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];
}

关于iphone - 如何将行号添加到 UITextView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2836162/

相关文章:

ios - 将 Datetime c# 转换为 Objective c 和反转

ios - 停止向 Apple 发送推送通知以进行传递

iphone - 如何在 iphone 中打印十进制值?

iphone - 隐藏 UIPageControl

iphone - 将 NSArray 转换为 NSMutableArray

objective-c - 无法识别同一 ViewController 中不同 View 上的 TextField

ios - React Native,应用程序在模拟器上运行,但不能在真实的 iPhone 上运行

ios - 第二次重新创建 MPMoviePlayerController 时设置 initialPlaybackTime 失败

iphone - 将字典值写入 iOS 文件时出现无法识别的选择器错误

iphone - 在 Xcode 中以编程方式创建文件夹 - Objective C