您的位置:首页 > 其它

FXLabel支持中文行距的简单修改

2013-01-10 12:07 513 查看
新版的FXLabel已经可以支持设置行间距了,但发现不能支持中文,遂简单改写了一下应急用

主要修改函数:

- (NSArray *)FXLabel_linesWithFont:(UIFont *)font

constrainedToSize:(CGSize)size

lineBreakMode:(NSLineBreakMode)lineBreakMode

lineSpacing:(CGFloat)lineSpacing

characterSpacing:(CGFloat)characterSpacing

kerningTable:(NSDictionary *)kerningTable

allowOrphans:(BOOL)allowOrphans

此函数中函数word的识别是根据“ ”空格区分的,中文字之间没有,所以识别上有问题。

简单的修改思路是将每个字符作为一个word,也就是类似NSLineBreakByCharWrapping模式

修改代码如下:

- (NSArray *)FXLabel_linesWithFont:(UIFont *)font
constrainedToSize:(CGSize)size
lineBreakMode:(NSLineBreakMode)lineBreakMode
lineSpacing:(CGFloat)lineSpacing
characterSpacing:(CGFloat)characterSpacing
kerningTable:(NSDictionary *)kerningTable
allowOrphans:(BOOL)allowOrphans
{
//TODO: handle lineBreakMode of type NSLineBreakByCharWrapping
//this will require splitting text into individual characters

//split text into words
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
for (int i=0; i<self.length; i++)
{
NSString *str = [self substringWithRange:NSMakeRange(i,1)];
NSLog(@"%@", str);
[array addObject:str];
}
NSArray *words = [NSArray arrayWithArray:array];

//    NSString *text = [self stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
//    text = [text stringByReplacingOccurrencesOfString:@"\n" withString:@" \n "];
// 空格作为分隔符
//    NSArray *words = [text componentsSeparatedByString:@" "];

words = [words filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]];

//calculate lines
NSInteger index = 0;
NSMutableArray *lines = [NSMutableArray array];
while (index < [words count])
{
NSInteger lineCount = [lines count];
if (lineCount && ((lineCount + 1) * font.lineHeight + lineCount * font.pointSize * lineSpacing) > size.height)
{
//append remaining text to last line
NSArray *remainingWords = [words subarrayWithRange:NSMakeRange(index, [words count] - index)];
NSString *line = [lines lastObject];
// 加回空格分隔符
//NSString *newLine = [line length]? [line stringByAppendingString:@" "]: @"";
NSString *newLine = [line length]? line : @"";
// 加回空格分隔符
//newLine = [newLine stringByAppendingString:[remainingWords componentsJoinedByString:@" "]];
newLine = [newLine stringByAppendingString:[remainingWords componentsJoinedByString:@""]];
newLine = [newLine stringByReplacingOccurrencesOfString:@"\n " withString:@"\n"];
newLine = [newLine stringByReplacingOccurrencesOfString:@" \n" withString:@"\n"];
[lines replaceObjectAtIndex:lineCount - 1 withObject:newLine];
break;
}
NSString *line = nil;
for (int i = index; i < [words count]; i++)
{
NSString *word = words[i];
// 加回空格分隔符
//NSString *newLine = line? [line stringByAppendingFormat:@" %@", word]: word;
NSString *newLine = line? [line stringByAppendingFormat:@"%@", word]: word;
CGFloat lineWidth = [newLine sizeWithFont:font
minFontSize:font.pointSize
actualFontSize:NULL
forWidth:INFINITY
lineBreakMode:lineBreakMode
characterSpacing:characterSpacing
kerningTable:kerningTable].width;

if ([word isEqualToString:@"\n"])
{
//add line and prepare for next
[lines addObject:line ?: @""];
index = i + 1;
break;
}
else if ([word isEqualToString:@"\r"])
{
//add line and prepare for next
[lines addObject:line ?: @""];
index = i + 1;
break;
}
else if (lineWidth > size.width && line)
{
//check for orphans
if (!allowOrphans && i > 0 &&
(i == [words count] - 1 || [words[i + 1] isEqualToString:@"\n"] || [words[i + 1] isEqualToString:@"\r"]) &&
![words[i - 1] FXLabel_isPunctuation])
{
//force line break
NSRange range = [line rangeOfString:@" " options:NSBackwardsSearch];
if (range.location != NSNotFound)
{
line = [line substringToIndex:range.location];
i --;
}
}

//add line and prepare for next
[lines addObject:line];
index = i;
break;
}
else if (i == [words count] - 1)
{
//add line and finish
[lines addObject:newLine];
index = i + 1;
break;
}
else
{
//continue
line = newLine;
}
}
}
return lines;
}


例子下载:Linespacing & Orphans

更正一下:

CGSize size = [str sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(320, 999999.0f) lineBreakMode:kCTLineBreakByCharWrapping
lineSpacing:0.8 characterSpacing:0 kerningTable:nil allowOrphans:NO];

CGRect frame = CGRectMake(0, 0, 320, size.height);

l1.frame = frame;

l1.text = str;

l1.backgroundColor = [UIColor clearColor];

l1.textColor = [UIColor redColor];

l1.lineSpacing = 1;

例子中的这段代码,计算size时的lineSpacing写成了0.8比label的设置小了,所以少分了一行

自行更正,我不改例子了

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐