iOS版。确定UILabel的最后一行宽度

时间:2012-04-17 14:21:45

标签: ios uilabel

家伙!我有一个多行标签,lineBreakMode设置为UILineBreakModeWordWrap。如何确定最后一行的宽度?感谢

4 个答案:

答案 0 :(得分:5)

我是这样做的。首先将标签的行放在NSArray中,然后检查最后一行的宽度。 在viewDidLoad中:

NSArray* lines = [self getSeparatedLinesFromLbl:srcLabel];
NSString *lastLine=[lines lastObject];
float lastLineWidth=[lastLine sizeWithFont:srcLabel.font constrainedToSize:boundingSize lineBreakMode:NSLineBreakByWordWrapping].width;

getSeparatedLinesFromLbl:

-(NSArray*)getSeparatedLinesFromLbl:(UILabel*)lbl
{
if ( lbl.lineBreakMode != NSLineBreakByWordWrapping )
{
    return nil;
}

NSMutableArray* lines = [NSMutableArray arrayWithCapacity:10];

NSCharacterSet* wordSeparators = [NSCharacterSet whitespaceAndNewlineCharacterSet];

NSString* currentLine = lbl.text;
int textLength = [lbl.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 = [lbl.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 = [lbl.text substringWithRange: rTest];

    CGSize sizeTest = [textTest sizeWithFont: lbl.font forWidth: 1024.0 lineBreakMode: NSLineBreakByWordWrapping];
    if ( sizeTest.width > lbl.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;
}

答案 1 :(得分:3)

自iOS 7.0起,您就可以使用此功能来做到这一点(也许您需要根据情况对文本容器进行更多调整):

modelBuilder.ComplexType<OLI_LU_BOOLEAN>()

然后,您可以确定日期标签的最后一行是否有足够的地方

用法示例:

CreateTable("imsparamed.TXLifeRequest1",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    PendingResponseOK_Value = c.String(),
                    PendingResponseOK_Id = c.Int(nullable: false)

                })

答案 2 :(得分:1)

Swift 3(IOS 10.3)

extension UILabel {
    func getSeparatedLines() -> [Any] {
        if self.lineBreakMode != NSLineBreakMode.byWordWrapping {
            self.lineBreakMode = .byWordWrapping
        }
        var lines = [Any]() /* capacity: 10 */
        let wordSeparators = CharacterSet.whitespacesAndNewlines
        var currentLine: String? = self.text
        let textLength: Int = (self.text?.characters.count ?? 0)
        var rCurrentLine = NSRange(location: 0, length: textLength)
        var rWhitespace = NSRange(location: 0, length: 0)
        var rRemainingText = NSRange(location: 0, length: textLength)
        var done: Bool = false
        while !done {
            // determine the next whitespace word separator position
            rWhitespace.location = rWhitespace.location + rWhitespace.length
            rWhitespace.length = textLength - rWhitespace.location
            rWhitespace = (self.text! as NSString).rangeOfCharacter(from: wordSeparators, options: .caseInsensitive, range: rWhitespace)
            if rWhitespace.location == NSNotFound {
                rWhitespace.location = textLength
                done = true
            }
            let rTest = NSRange(location: rRemainingText.location, length: rWhitespace.location - rRemainingText.location)
            let textTest: String = (self.text! as NSString).substring(with: rTest)
            let fontAttributes: [String: Any]? = [NSFontAttributeName: font]
            let maxWidth = (textTest as NSString).size(attributes: fontAttributes).width
            if maxWidth > self.bounds.size.width {
                lines.append(currentLine?.trimmingCharacters(in: wordSeparators) ?? "")
                rRemainingText.location = rCurrentLine.location + rCurrentLine.length
                rRemainingText.length = textLength - rRemainingText.location
                continue
            }
            rCurrentLine = rTest
            currentLine = textTest
        }
        lines.append(currentLine?.trimmingCharacters(in: wordSeparators) ?? "")
        return lines
    }

    var lastLineWidth: CGFloat {
        let lines: [Any] = self.getSeparatedLines()
        if !lines.isEmpty {
            let lastLine: String = (lines.last as? String)!
            let fontAttributes: [String: Any]? = [NSFontAttributeName: font]
            return (lastLine as NSString).size(attributes:     fontAttributes).width
        }
        return 0
    }
}

<强> 用法

print(yourLabel.lastLineWidth)
  

Swift 3(IOS 10.3)

答案 3 :(得分:0)

我发现NSLayoutManager为此提供了API:


$user->profile()->associate($user);

所以,我认为我们可以这样做:

// Returns the usage rect for the line fragment in which the given glyph is laid and (optionally) by reference the whole range of glyphs that are in that fragment.  
// This will cause glyph generation and layout for the line fragment containing the specified glyph, or if non-contiguous layout is not enabled, up to and including that line fragment.  
// Line fragment used rects are always in container coordinates.
open func lineFragmentUsedRect(forGlyphAt glyphIndex: Int, effectiveRange effectiveGlyphRange: NSRangePointer?) -> CGRect