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

新版的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模式


修改代码如下:

  1. - (NSArray *)FXLabel_linesWithFont:(UIFont *)font  
  2.                  constrainedToSize:(CGSize)size  
  3.                      lineBreakMode:(NSLineBreakMode)lineBreakMode  
  4.                        lineSpacing:(CGFloat)lineSpacing  
  5.                   characterSpacing:(CGFloat)characterSpacing  
  6.                       kerningTable:(NSDictionary *)kerningTable  
  7.                       allowOrphans:(BOOL)allowOrphans  
  8. {  
  9.     //TODO: handle lineBreakMode of type NSLineBreakByCharWrapping  
  10.     //this will require splitting text into individual characters  
  11.       
  12.     //split text into words  
  13.     NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];  
  14.     for (int i=0; i<self.length; i++)  
  15.     {  
  16.         NSString *str = [self substringWithRange:NSMakeRange(i,1)];  
  17.         NSLog(@"%@", str);  
  18.         [array addObject:str];  
  19.     }  
  20.     NSArray *words = [NSArray arrayWithArray:array];  
  21.   
  22. //    NSString *text = [self stringByReplacingOccurrencesOfString:@"\t" withString:@" "];  
  23. //    text = [text stringByReplacingOccurrencesOfString:@"\n" withString:@" \n "];  
  24.     // 空格作为分隔符  
  25. //    NSArray *words = [text componentsSeparatedByString:@" "];  
  26.   
  27.     words = [words filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]];  
  28.       
  29.     //calculate lines  
  30.     NSInteger index = 0;  
  31.     NSMutableArray *lines = [NSMutableArray array];  
  32.     while (index < [words count])  
  33.     {  
  34.         NSInteger lineCount = [lines count];  
  35.         if (lineCount && ((lineCount + 1) * font.lineHeight + lineCount * font.pointSize * lineSpacing) > size.height)  
  36.         {  
  37.             //append remaining text to last line  
  38.             NSArray *remainingWords = [words subarrayWithRange:NSMakeRange(index, [words count] - index)];  
  39.             NSString *line = [lines lastObject];  
  40.             // 加回空格分隔符  
  41.             //NSString *newLine = [line length]? [line stringByAppendingString:@" "]: @"";  
  42.             NSString *newLine = [line length]? line : @"";  
  43.             // 加回空格分隔符  
  44.             //newLine = [newLine stringByAppendingString:[remainingWords componentsJoinedByString:@" "]];  
  45.             newLine = [newLine stringByAppendingString:[remainingWords componentsJoinedByString:@""]];  
  46.             newLine = [newLine stringByReplacingOccurrencesOfString:@"\n " withString:@"\n"];  
  47.             newLine = [newLine stringByReplacingOccurrencesOfString:@" \n" withString:@"\n"];  
  48.             [lines replaceObjectAtIndex:lineCount - 1 withObject:newLine];  
  49.             break;  
  50.         }  
  51.         NSString *line = nil;  
  52.         for (int i = index; i < [words count]; i++)  
  53.         {  
  54.             NSString *word = words[i];  
  55.             // 加回空格分隔符  
  56.             //NSString *newLine = line? [line stringByAppendingFormat:@" %@", word]: word;  
  57.             NSString *newLine = line? [line stringByAppendingFormat:@"%@", word]: word;  
  58.             CGFloat lineWidth = [newLine sizeWithFont:font  
  59.                                           minFontSize:font.pointSize  
  60.                                        actualFontSize:NULL  
  61.                                              forWidth:INFINITY  
  62.                                         lineBreakMode:lineBreakMode  
  63.                                      characterSpacing:characterSpacing  
  64.                                          kerningTable:kerningTable].width;  
  65.               
  66.             if ([word isEqualToString:@"\n"])  
  67.             {  
  68.                 //add line and prepare for next  
  69.                 [lines addObject:line ?: @""];  
  70.                 index = i + 1;  
  71.                 break;  
  72.             }  
  73.             else if ([word isEqualToString:@"\r"])  
  74.             {  
  75.                 //add line and prepare for next  
  76.                 [lines addObject:line ?: @""];  
  77.                 index = i + 1;  
  78.                 break;  
  79.             }  
  80.             else if (lineWidth > size.width && line)  
  81.             {  
  82.                 //check for orphans  
  83.                 if (!allowOrphans && i > 0 &&  
  84.                     (i == [words count] - 1 || [words[i + 1] isEqualToString:@"\n"] || [words[i + 1] isEqualToString:@"\r"]) &&  
  85.                     ![words[i - 1] FXLabel_isPunctuation])  
  86.                 {  
  87.                     //force line break  
  88.                     NSRange range = [line rangeOfString:@" " options:NSBackwardsSearch];  
  89.                     if (range.location != NSNotFound)  
  90.                     {  
  91.                         line = [line substringToIndex:range.location];  
  92.                         i --;  
  93.                     }  
  94.                 }  
  95.                   
  96.                 //add line and prepare for next  
  97.                 [lines addObject:line];  
  98.                 index = i;  
  99.                 break;  
  100.             }  
  101.             else if (i == [words count] - 1)  
  102.             {  
  103.                 //add line and finish  
  104.                 [lines addObject:newLine];  
  105.                 index = i + 1;  
  106.                 break;  
  107.             }  
  108.             else  
  109.             {  
  110.                 //continue  
  111.                 line = newLine;  
  112.             }  
  113.         }  
  114.     }  
  115.     return lines;  
  116. }  


例子下载:Linespacing & Orphans


更正一下:

    CGSize size = [str sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(320, 999999.0f) lineBreakMode:kCTLineBreakByCharWrappinglineSpacing: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的设置小了,所以少分了一行

自行更正,我不改例子了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值