【问题标题】:Drawing ruled lines on a UITextView for IPhone在 iPhone 的 UITextView 上绘制格线
【发布时间】:2011-03-30 08:30:37
【问题描述】:

我想在 iPhone 上创建一个类似于笔记应用程序的视图,因此需要视图按照笔记应用程序具有格线,我在需要获取字体指标然后绘制线条的窗口中完成了此操作到设备上下文中,有没有人在 UITextView 中这样做过,如果有的话会得到一些帮助

【问题讨论】:

    标签: iphone uitextview


    【解决方案1】:

    子类 UITextView。覆盖-drawRect:

    - (void)drawRect:(CGRect)rect
    {    
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
        CGContextSetLineWidth(context, self.lineWidth);
        CGFloat strokeOffset = (self.lineWidth / 2);
    
        CGFloat rowHeight = self.font.lineHeight;
        if (rowHeight > 0) {
            CGRect rowRect = CGRectMake(self.contentOffset.x, - self.bounds.size.height, self.contentSize.width, rowHeight);
            while (rowRect.origin.y < (self.bounds.size.height + self.contentSize.height)) {
                CGContextMoveToPoint(context, rowRect.origin.x + strokeOffset, rowRect.origin.y + strokeOffset);
                CGContextAddLineToPoint(context, rowRect.origin.x + rowRect.size.width + strokeOffset, rowRect.origin.y + strokeOffset);
                CGContextDrawPath(context, kCGPathStroke);
                rowRect.origin.y += rowHeight;
            }
        }
    }
    

    当你初始化文本视图时,一定要将 contentMode 设置为 UIViewContentModeRedraw。否则行将不会随着文本滚动。

    self.contentMode = UIViewContentModeRedraw;
    

    这并不完美。理想情况下,您应该只绘制通过的矩形。但我很懒,这满足了我的需要。

    【讨论】:

    • 你能扩展一下吗?例如。什么是行号?
    • 对不起。当我复制和粘贴时,只留下代码。我不相信它与这段代码有关。我已将其删除。
    • @DaveBatton self.lineWidth 是什么?是静态的还是动态的??
    • self.lineWidth 是一个公共 CGFloat 属性。
    【解决方案2】:

    我认为这行得通,但我觉得它已经被黑了,我并不完全理解 UITextView 类的机制;

    首先,您必须将以下内容添加到您的委托中以强制在滚动时重绘

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {   
        // NSLog(@"scrollViewDidScroll The scroll offset is ---%f",scrollView.contentOffset.y);
        [noteText setNeedsDisplay];
    }
    

    然后在子类中这样实现drawRect

    - (void)drawRect:(CGRect)rect {
        // Drawing code
        // Get the graphics context
        CGContextRef ctx = UIGraphicsGetCurrentContext();
    
        [super drawRect:rect];
    
        // Get the height of a single text line
        NSString *alpha = @"ABCD";
        CGSize textSize = [alpha sizeWithFont:self.font constrainedToSize:self.contentSize lineBreakMode:UILineBreakModeWordWrap];
        NSUInteger height = textSize.height;
    
        // Get the height of the view or contents of the view whichever is bigger
        textSize = [self.text sizeWithFont:self.font constrainedToSize:self.contentSize lineBreakMode:UILineBreakModeWordWrap];
        NSUInteger contentHeight = (rect.size.height > textSize.height) ? (NSUInteger)rect.size.height : textSize.height;
    
        NSUInteger offset = 6 + height; // MAGIC Number 6 to offset from 0 to get first line OK ???
        contentHeight += offset;
        // Draw ruled lines
        CGContextSetRGBStrokeColor(ctx, .8, .8, .8, 1);
        for(int i=offset;i < contentHeight;i+=height) {
            CGPoint lpoints[2] = { CGPointMake(0, i), CGPointMake(rect.size.width, i) };
            CGContextStrokeLineSegments(ctx, lpoints, 2);
        }
    }
    

    还在担心这个神奇的数字 6

    鲍勃

    【讨论】:

    • 很好的解决方案。但我已将@Dave 的self.contentMode = UIViewContentModeRedraw; 添加到子类的init 方法中,而不是您的setNeedsDisplay 方法中。
    【解决方案3】:

    您可以尝试使用带格线的图像设置 textView 的背景颜色

    textView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"RuledLinesPage.png"]];
    

    如果要填充颜色的区域大于图像,则带有图案图像的颜色会创建平铺图像。所以你必须确保图像尺寸是正确的尺寸/平铺(我不认为'平铺'是一个真实的词,但我希望你明白我的意思)。此外,您还必须创建带有格线的图像,以最好地匹配您 textView 的字体。

    祝你好运。

    【讨论】:

    • 如果可行的话,那就太聪明了。可以通过编程方式生成图像以适应字体。
    【解决方案4】:

    @lukya, 您的解决方案有点混乱,因为当我们滚动 UITextView 时,文本只会滚动,而将线条(来自图像)留在原处。

    更好的解决方案是将子视图添加到您绘制线条的文本视图中。您需要在文本视图中添加观察者,以跟踪其在文本增加/减少时内容大小的变化。

    【讨论】:

    • 这应该是对答案的评论,而不是“答案”本身。
    猜你喜欢
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多