多行UILabel无字包装? [英] Multiline UILabel without word wrap?

查看:83
本文介绍了多行UILabel无字包装?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以有一个 UILabel ,它由多个 \\\



假设我有一些文本,如下所示:



<


  • 这是一个很长的第一行文字,

  • 我希望它出现在我的 UILabel / p>

     
    1.这是一个很长的第一行文本...
    2.短行
    3.另一个短线

    然而,发生的是我得到这个:

     
    1.这是一个很长的第一行文本
    太长,不能水平
    2.短行...

    第三行被截断。我已将行数设置为 3 ,但它仍然包装第一个长行。它似乎没有什么问题,我设置行打破属性在标签上 - 它总是包装第一行。是否有任何方法可以完全阻止标签上的包装?

    解决方案

    我不认为这是可能的任何设置适用于您的标签。一种方法是将字符串拆分为单独的行,截断任何需要它的行,使它(添加一个省略号)符合一行,然后将字符串放回换行符。这样的东西应该适用于任何行数,

      @interface ViewController()
    @property )IBOutlet UILabel * label;
    @property(nonatomic)CGFloat ellipsisWidth;
    @end

    @implementation ViewController

    - (void)viewDidLoad {
    [super viewDidLoad];
    NSString * text = @这是一个很长的第一行文本太长,不能水平适合\\\
    Short line \\\
    Another短行;
    NSString * ellipsis = @...
    self.ellipsisWidth = [ellipsis sizeWithAttributes:@ {NSFontAttributeName:self.label.font}]。width;

    __block NSMutableString * truncatedString = [@mutableCopy];
    [text enumerateLinesUsingBlock:^(NSString * line,BOOL * stop){
    [truncatedString appendFormat:@%@ \\\
    ,[self oneLineOfString:line withFont:self.label.font]] ;
    }];
    NSString * finalString = [truncatedString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
    self.label.numberOfLines = 0;
    self.label.text = finalString;
    }

    - (NSString *)oneLineOfString:(NSString *)aLine withFont:(UIFont *)font {
    __block NSString * singleLine = nil;
    __block NSString * lastFragment;

    [aLine enumerateSubstringsInRange:NSMakeRange(0,aLine.length)options:NSStringEnumerationByWords usingBlock:^(NSString * substring,NSRange substringRange,NSRange enclosingRange,BOOL * stop){
    NSString * textFragment = [aLine substringToIndex:(substringRange.location + substringRange.length)];
    CGRect textRect = [textFragment boundingRectWithSize:CGSizeMake(CGFLOAT_MAX,CGFLOAT_MAX)options:NSStringDrawingUsesLineFragmentOrigin attributes:@ {NSFontAttributeName:font} context:nil];
    if(textRect.size.width> = self.label.bounds.size.width - self.ellipsisWidth){
    singleLine = [lastFragment stringByAppendingString:@...];
    * stop = YES;
    }
    lastFragment = textFragment;
    }];
    if(!singleLine)singleLine = aLine; //它不需要被截断,所以返回传入行
    return singleLine;
    }

    如果要按字符而不是字进行截断,可以传递NSStringEnumerationByComposedCharacterSequences而不是NSStringEnumerationByWords到
    的选项参数enumerateSubstringsInRange:options:usingBlock:。



    当然,你可以用简单的方法;堆叠3个标签在彼此的顶部,并给每一个你的文本的一行)。


    Is it possible to have a UILabel that consists of multiple \n-delimited lines to have lines with their width > the label width to be truncated and not wrapped?

    Suppose I have some text like the following:

    1. This is a really long first line of text that is too long to fit horizontally
    2. Short line
    3. Another short line

    I want this to appear in my UILabel like so:

    1. This is a really long first line of text...
    2. Short line
    3. Another short line
    

    However what is happening is I'm getting this:

    1. This is a really long first line of text  
    that is too long to fit horizontally
    2. Short line...
    

    The third line is getting cut off. I've set the number of lines to 3, but it is still wrapping the first long line. It doesn't seem to matter what I set the line breaks property to on the label--it always wraps that first line. Is there any way to prevent wrapping completely on the label?

    解决方案

    I don't think this is possible with any setting you can apply to your label. One way to do it, is to break the string into its individual lines, truncate any line that needs it so that it (with an added ellipsis) fits on one line, then put the string back together with line breaks. Something like this should work for any number of lines,

    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UILabel *label;
    @property (nonatomic) CGFloat ellipsisWidth;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSString *text = @"This is a really long first line of text that is too long to fit horizontally\nShort line\nAnother short line";
        NSString *ellipsis = @"...";
        self.ellipsisWidth = [ellipsis sizeWithAttributes:@{NSFontAttributeName:self.label.font}].width;
    
        __block NSMutableString *truncatedString = [@"" mutableCopy];
        [text enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
            [truncatedString appendFormat:@"%@\n", [self oneLineOfString:line withFont:self.label.font]];
        }];
        NSString *finalString = [truncatedString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
        self.label.numberOfLines = 0;
        self.label.text = finalString;
    }
    
    -(NSString *)oneLineOfString:(NSString *) aLine withFont:(UIFont *) font {
        __block NSString *singleLine = nil;
        __block NSString *lastFragment;
    
        [aLine enumerateSubstringsInRange:NSMakeRange(0, aLine.length) options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
            NSString *textFragment = [aLine substringToIndex:(substringRange.location + substringRange.length)];
            CGRect textRect = [textFragment boundingRectWithSize:CGSizeMake(CGFLOAT_MAX ,CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil];
            if (textRect.size.width >= self.label.bounds.size.width - self.ellipsisWidth) {
                singleLine = [lastFragment stringByAppendingString:@"..."];
                *stop = YES;
            }
            lastFragment = textFragment;
        }];
        if (!singleLine) singleLine = aLine; // it doesn't need to be truncated, so return the passed in line
        return singleLine;
    }
    

    If you want to truncate by character instead of by word, you can pass NSStringEnumerationByComposedCharacterSequences instead of NSStringEnumerationByWords to the options parameter of enumerateSubstringsInRange:options:usingBlock:.

    Of course, you could do it the easy way; stack 3 labels on top of each other, and give each one a line of your text :)

    这篇关于多行UILabel无字包装?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆