由UILineBreakModeWordWrap产生的UILabel行 [英] Resulting lines of UILabel with UILineBreakModeWordWrap

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

问题描述

我有一个UILabel,其大小是用 sizeWithFont:方法计算的。换行模式设置为 UILineBreakModeWordWrap (使用 sizeWithFont:计算大小时使用相同的标志)...

I have a UILabel whose size is calculated with sizeWithFont: method. The line break mode is set to UILineBreakModeWordWrap (same flag is used when calculating the size with sizeWithFont:)...

一切都很好,标签大小合适,并根据需要显示我的文字。

Everything works great, label is properly sized and displays my text as required.

现在我需要知道用于显示标签的行(或使用 sizeWithFont:时生成的行)。我可以在技术上编写我自己的基于空格/插入符返回的断行实现,但是它不会像Apple的实现那样得到保证,因此生成的行不会是用于计算文本大小的行,没关系重新发明轮子的事实。

Now I need to know the lines that are used to display the label (or the lines that are generated when sizeWithFont: is used). I could technically write my own implementation of line breaking based on spaces/caret returns, but then it's not going to be guaranteed the same way as Apple's implementation and hence the resulting lines will not be the ones that are used to calculate the size of text, nevermind the fact of reinventing the wheel.

理想情况下,我会传递我的字符串,指定宽度和换行模式并接收表示视觉线条的字符串数组文本。

Ideally, I would pass my string, specify the width and line break mode and receive an array of strings representing the visual lines of text.

如何以最优雅的方式实现这一目标?

Any ideas how to make this happen in the most elegant way?

推荐答案

我认为没有任何灵丹妙药。

I don't think there is any silver bullet for this.

这是一个类别方法,似乎适用于我投入的几个基本测试用例。不能保证它不会破坏复杂的东西!

Here is a category method that seems to work for the few basic test cases I threw at it. No guarantees it won't break with something complex!

它的工作方式是通过字符串测试来查看一系列单词是否适合宽度标签。当它计算当前范围太宽时,它会将最后拟合范围记录为一行。

The way it works is to move through the string testing to see if a range of words fits in the width of the label. When it calculates that the current range is too wide it records the last-fitting range as a line.

我并不认为这是有效的。更好的方法就是实现自己的UILabel ...

I don't claim this is efficient. A better way may just to be to implement your own UILabel...

@interface UILabel (Extensions)

- (NSArray*) lines;

@end

@implementation UILabel (Extensions)

- (NSArray*) lines
{
    if ( self.lineBreakMode != UILineBreakModeWordWrap )
    {
        return nil;
    }

    NSMutableArray* lines = [NSMutableArray arrayWithCapacity:10];

    NSCharacterSet* wordSeparators = [NSCharacterSet whitespaceAndNewlineCharacterSet];

    NSString* currentLine = self.text;
    int textLength = [self.text length];

    NSRange rCurrentLine = NSMakeRange(0, textLength);
    NSRange rWhitespace = NSMakeRange(0,0);
    NSRange rRemainingText = NSMakeRange(0, textLength);
    BOOL done = NO;
    while ( !done )
    {
        // determine the next whitespace word separator position
        rWhitespace.location = rWhitespace.location + rWhitespace.length;
        rWhitespace.length = textLength - rWhitespace.location;
        rWhitespace = [self.text rangeOfCharacterFromSet: wordSeparators options: NSCaseInsensitiveSearch range: rWhitespace];
        if ( rWhitespace.location == NSNotFound )
        {
            rWhitespace.location = textLength;
            done = YES;
        }

        NSRange rTest = NSMakeRange(rRemainingText.location, rWhitespace.location-rRemainingText.location);

        NSString* textTest = [self.text substringWithRange: rTest];

        CGSize sizeTest = [textTest sizeWithFont: self.font forWidth: 1024.0 lineBreakMode: UILineBreakModeWordWrap];
        if ( sizeTest.width > self.bounds.size.width )
        {
            [lines addObject: [currentLine stringByTrimmingCharactersInSet:wordSeparators]];
            rRemainingText.location = rCurrentLine.location + rCurrentLine.length;
            rRemainingText.length = textLength-rRemainingText.location;
            continue;
        }

        rCurrentLine = rTest;
        currentLine = textTest;
    }

    [lines addObject: [currentLine stringByTrimmingCharactersInSet:wordSeparators]];

    return lines;
}

@end

像这样使用:

NSArray* lines = [_theLabel lines];

int count = [lines count];

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

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