我已经搜索了很多类似的问题,我决定通过这里问这个,如果已经被问到我找不到它并抱歉。
我发现:UITextView like iPhone Notes application重定向到这里:http://www.cocoanetics.com/2010/03/stuff-you-learn-from-reverse-engineering-notes-app/但是在逆向工程中没有完整的代码示例!
我正在为iphone创建一个应用程序,它可以存储并让人们像iphone中的notes.app一样输入文本。我需要在我知道的情况下为文本加下划线,我需要在uitextview中进行操作,uitextview是uiscrollview的子类。
如果有人有任何建议让我很开心..
谢谢..
答案 0 :(得分:1)
当我需要使用UILabel执行此操作时,我创建了UIView的子类并自己实现了自定义绘图。它非常详细,但并不复杂。我最终传递了类似HTML的语法,处理粗体(< b>和< / b>)和新行(< br>)格式。我认为你可能会对下划线使用(< u>和< / u>)做同样的事情。
基本上,我的技术是使用类似HTML的标记拆分字符串(首先在“br”标签上吐痰,然后在“b”标签上吐痰)然后将每个子字符串拆分为“单词”,然后处理测量和单独绘制每个单词。如果一个单词不适合当前行,我将换行到下一行。它并不完美,并且它不适用于很多场景(例如,新的行标签不能放在粗体标签内),但它适用于我的意图。
不幸的是,我不知道为什么在一些(大多数/全部?)iOS基本文本显示控件中不支持文本格式化。
修改/更新强>
我会继续添加UIView子类(替换UILabel)我写的。使用风险自负! : - )
MMFormattedTextView.h
#import <UIKit/UIKit.h><br>
@interface MMFormattedTextView : UIView {
int InsetLeft;
int InsetTop;
NSString *LabelText;
UIFont *LabelFont;
}
@property (assign, nonatomic) int InsetLeft;
@property (assign, nonatomic) int InsetTop;
@property (strong, nonatomic) NSString *LabelText;
@property (strong, nonatomic) UIFont *LabelFont;
- (NSInteger)numberOfLinesForRect:(CGRect)rect;
@end
MMFormattedTextView.m
#import "MMFormattedTextView.h"
@implementation MMFormattedTextView
@synthesize InsetLeft;
@synthesize InsetTop;
@synthesize LabelFont;
@synthesize LabelText;
// LIMITATION: Each bolded section must reside IN BETWEEN <br> tags; it MAY NOT span <br> tags!!!!
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextClearRect(ctx, rect);
// Sets up the first position, which is 1 line "off the top",
// adjusted so that the text will be centered when it's all drawn
CGFloat howManyLinesWouldFit = rect.size.height / [[self LabelFont] lineHeight];
NSInteger howManyLinesDoWeHave = [self numberOfLinesForRect:rect];
CGFloat lineOffset = (howManyLinesWouldFit - howManyLinesDoWeHave) / 2.0;
CGPoint topLeft = CGPointMake([self InsetLeft], [self InsetTop] - [[self LabelFont] lineHeight] + (lineOffset * [[self LabelFont] lineHeight]));
// Split the text into hard-split lines (actual <br> tags in the text)
NSArray *lines = [[self LabelText] componentsSeparatedByString:@"<br>"];
// Iterate through each hard-coded line
for (NSString *line in lines) {
// Iterate to the next line
topLeft = CGPointMake([self InsetLeft], topLeft.y + [[self LabelFont] lineHeight]);
NSArray *pieces = [line componentsSeparatedByString:@"<b>"];
BOOL bold = YES;
for (NSString *piece in pieces) {
bold = !bold;
UIFont *fontToUse;
if (bold) {
fontToUse = [UIFont boldSystemFontOfSize:[[self LabelFont] pointSize]];
} else {
fontToUse = [UIFont systemFontOfSize:[[self LabelFont] pointSize]];
}
NSArray *words = [piece componentsSeparatedByString:@" "];
for (NSString *word in words) {
if ([word isEqualToString:@""]) continue;
NSString *wordWithSpace = [NSString stringWithFormat:@"%@ ", word];
CGSize wordSize = [wordWithSpace sizeWithFont:fontToUse];
if ((topLeft.x + wordSize.width) > (rect.size.width - [self InsetLeft])) {
// This runs off this line, so go to the next line
topLeft = CGPointMake([self InsetLeft], topLeft.y + [[self LabelFont] lineHeight]);
}
[wordWithSpace drawAtPoint:topLeft withFont:fontToUse];
topLeft = CGPointMake(topLeft.x + wordSize.width, topLeft.y);
}
}
}
}
- (NSInteger)numberOfLinesForRect:(CGRect)rect {
int retVal = 0;
int left = [self InsetLeft];
NSArray *lines = [[self LabelText] componentsSeparatedByString:@"<br>"];
// Iterate through each hard-coded line
for (NSString *line in lines) {
// Iterate to the next line
retVal = retVal + 1;
left = [self InsetLeft];
NSArray *pieces = [line componentsSeparatedByString:@"<b>"];
BOOL bold = YES;
for (NSString *piece in pieces) {
bold = !bold;
UIFont *fontToUse;
if (bold) {
fontToUse = [UIFont boldSystemFontOfSize:[[self LabelFont] pointSize]];
} else {
fontToUse = [UIFont systemFontOfSize:[[self LabelFont] pointSize]];
}
NSArray *words = [piece componentsSeparatedByString:@" "];
for (NSString *word in words) {
if ([word isEqualToString:@""]) continue;
NSString *wordWithSpace = [NSString stringWithFormat:@"%@ ", word];
CGSize wordSize = [wordWithSpace sizeWithFont:fontToUse];
if ((left + wordSize.width) > (rect.size.width - [self InsetLeft])) {
// This runs off this line, so go to the next line
retVal = retVal + 1;
left = [self InsetLeft];
}
left = left + wordSize.width;
}
}
}
return retVal;
}
@end