UITextView 格线背景但线高错误
Posted
技术标签:
【中文标题】UITextView 格线背景但线高错误【英文标题】:UITextView ruled line background but wrong line height 【发布时间】:2011-03-21 08:36:20 【问题描述】:我有一个 UITextView,用户可以在其中创建注释并保存到 plist 文件中。 我希望能够像普通笔记本一样显示线条。我遇到的问题是 文本将无法正确对齐。
下图很好地解释了这个问题。
这是我用来创建像 Notes.app 这样的线条的背景
这是我为UITextView
创建背景的代码:
textView.font = [UIFont fontWithName:@"MarkerFelt-Thin" size:19.0];
textView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Notes.png"]];
我知道UIFont.lineHeight
属性仅适用于 > ios 4.x。
所以我想知道我的问题是否有其他解决方案?
【问题讨论】:
【参考方案1】:您应该尝试以编程方式绘制线条,而不是使用图像。下面是一些示例代码,说明如何实现这一点。您可以继承 UITextView
并覆盖它的 drawRect:
方法。
NoteView.h
#import <UIKit/UIKit.h>
@interface NoteView : UITextView <UITextViewDelegate>
@end
NoteView.m
#import "NoteView.h"
@implementation NoteView
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
self.backgroundColor = [UIColor colorWithRed:1.0f green:1.0f blue:0.6f alpha:1.0f];
self.font = [UIFont fontWithName:@"MarkerFelt-Thin" size:19];
return self;
- (void)drawRect:(CGRect)rect
//Get the current drawing context
CGContextRef context = UIGraphicsGetCurrentContext();
//Set the line color and width
CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.2f].CGColor);
CGContextSetLineWidth(context, 1.0f);
//Start a new Path
CGContextBeginPath(context);
//Find the number of lines in our textView + add a bit more height to draw lines in the empty part of the view
NSUInteger numberOfLines = (self.contentSize.height + self.bounds.size.height) / self.font.leading;
//Set the line offset from the baseline. (I'm sure there's a concrete way to calculate this.)
CGFloat baselineOffset = 6.0f;
//iterate over numberOfLines and draw each line
for (int x = 0; x < numberOfLines; x++)
//0.5f offset lines up line with pixel boundary
CGContextMoveToPoint(context, self.bounds.origin.x, self.font.leading*x + 0.5f + baselineOffset);
CGContextAddLineToPoint(context, self.bounds.size.width, self.font.leading*x + 0.5f + baselineOffset);
//Close our Path and Stroke (draw) it
CGContextClosePath(context);
CGContextStrokePath(context);
@end
MyViewController.h
#import <UIKit/UIKit.h>
#import "NoteView.h"
@interface MyViewController : UIViewController <UITextViewDelegate>
NoteView *note;
@property (nonatomic, retain) NoteView *note;
@end
MyViewController.m
#import "MyViewController.h"
#import "NoteView.h"
#define KEYBOARD_HEIGHT 216
@implementation MyViewController
@synthesize note;
- (void)loadView
[super loadView];
self.note = [[[NoteView alloc] initWithFrame:self.view.bounds] autorelease];
[self.view addSubview:note];
note.delegate = self;
note.text = @"This is the first line.\nThis is the second line.\nThis is the ... line.\nThis is the ... line.\nThis is the ... line.\nThis is the ... line.\nThis is the ... line.\n";
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
[note setNeedsDisplay];
- (void)textViewDidBeginEditing:(UITextView *)textView
CGRect frame = self.view.bounds;
frame.size.height -= KEYBOARD_HEIGHT;
note.frame = frame;
- (void)textViewDidEndEditing:(UITextView *)textView
note.frame = self.view.bounds;
- (void)dealloc
[note release];
[super dealloc];
查看 Apple 的 Managing the Keyboard 文档,特别是“移动位于键盘下方的内容”。它解释了如何监听 NSNotifcations 并正确调整你的视图。
【讨论】:
好的,我想我现在关注您添加更多文本时出现的行。我将编辑答案,将视图的高度添加到内容大小的高度,并且应该用线条覆盖整个视图。 好的,我明白了,谢谢。如果您单击 Enter 并创建带有文本的新行,如果您的解决方案没有阻止这种情况的发生,文本在键盘下将不可见,那么您是否可以看到这些行不再正确对齐?如果您只键入三行,那么一切都是完美的,但是一旦它变得更多 NoteView.frame.size.height 线条被错误地绘制。你遇到过这种情况吗? 好吧,这真是太棒了。我将它与从 XIB 加载的文本视图一起使用 - 只需制作一个 UITextView 并将其类设置为 NoteView,就完成了。工作出色。我做了一个更改,我从 1 开始 for 循环,这样它就不会在第一行文本上方画一条线 - 看起来更漂亮,更像是一个真正的记事本。但实际上,这个答案超出了 *** 的预期。 不要忘记在initWithFrame:
中添加self.contentMode = UIViewContentModeRedraw;
,这样文本和行会一起滚动。否则,绝对很棒的解决方案!
我不确定它什么时候坏了,但是 font.leading 属性总是为我返回 0。相反,您应该使用在 iOS 9 上完全可以正常工作的 font.lineHeight【参考方案2】:
我认为问题出在您的图像上,线上方的黄色空间造成了问题。
您应该编辑图像。
干得好。
【讨论】:
这似乎是两件事的结合:我删除的黄色空间使它看起来每行的行高都相同。当我解决这个问题时,问题变得非常清楚: UITextView 中的文本有一个顶部填充,可以阻止文本完美对齐。边距可以用 contentInset 解决,但不能用 padding 解决。有人知道如何修复顶部填充吗? CSS 中的等价物是:padding-top:0px 是的,你说得对。我自己检查一下。但仍然无法解决这个问题。 contentInset 属性不适用于我的解决方案,因为背景随着 contentInset 移动。这只是需要移动的内容。我不明白为什么 UITextView 默认有一个 15px 左右的填充。我不知道在我的研究之后这是否可以调整,我想我需要寻找一些替代方法来解决它。过去这里有人做过吗? 我想在我的上一个客户项目中这样做。然后由于许多困难,我离开了所有这些线。但如果你找到解决方案,那么你应该与我们分享。以上是关于UITextView 格线背景但线高错误的主要内容,如果未能解决你的问题,请参考以下文章
当通过点击背景关闭 UITextView 的键盘时,我在 didSelectRowAt 中得到错误的 indexPath