2010-12-12 14 views
12

UILabelのある行のテキストを簡単に取得する(または単に表示する)方法はありますか?UILabelのn番目の行からテキストを取得する方法は?

私のUILabelは自分のテキストを正しく表示して美しくレイアウトしていますが、時には特定の行を表示する必要がある場合もありますが、明らかに私はUILabelがこれを行うためにすべての配置を行っているかを知る必要があります。

これは部分文字列を使って簡単に行うことができますが、その行の開始点と終了点を知る必要があることがわかります。

また、UILabelのフレームに何らかのオフセットがあっても、表示したくない残りのコンテンツを非表示にすると、UILabelをスクロールできます。

私は、これがどのように簡単に行えるかを示す何かを明らかにすることはできませんでした。誰もが良いアイデアを持っていますか?

答えて

4

iphaaw

おかげ

私は( "takethenline" 方式のように)これを行うためのネイティブな方法はないと思います。
私は難しい解決策を見つけ出すことができますが、私は最良のものであるかどうかはわかりません。
ラベルを単語の配列に分割できます。
そして、あなたがループ配列を可能性があり、このようなその言葉まで、テキストの高さを確認してください。

NSString *texttocheck; 
float old_height = 0; 
int linenumber = 0; 

for (x=0; x<[wordarray lenght]; x++) { 
    texttocheck = [NSString stringWithFormat:@"%@ %@", texttocheck, [wordarray objectAtIndex:x]]; 

    float height = [text sizeWithFont:textLabel.font 
        constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
         lineBreakMode:UILineBreakModeWordWrap].height; 

    if (old_height < height) { 
     linenumber++; 
    } 
} 

は、高さが変化した場合、それは、単語の前に改行がありますを意味します。
構文が正しく書かれているかどうかを確認することができないため、自分で確認する必要があります。

0

すべての文字が同じサイズで表示されている場合、つまり、共通のサイズのボックスに囲まれている場合は、その文字を利用できます。

そうしないと、表示フォント内の各文字のサイズを照会し、その行を計算することができます。

あなたの計算は、Appleが何をしているのかとは異なるかもしれません。その場合、テキストフレームの描画を無効にすることをお勧めします。このために文書内のコアテキストを調べます。

(私はこの間違ってやっているかもしれませんが、ドキュメントに与えられたとして、私はAppleの方法を見つけることができませんでしたが、非常に正確だったので、私は何か他のものをした自分自身。)

19

私はそれを発見したためのより良い方法を持っています。

これはCoreText.frameworkの助けを借りて得ることができます。

1.Add CoreText.framework
2.インポート#import <CoreText/CoreText.h>
は、その後の方法の下に使用します。

- (NSArray *)getLinesArrayOfStringInLabel:(UILabel *)label { 
    NSString *text = [label text]; 
    UIFont *font = [label font]; 
    CGRect rect = [label frame]; 

    CTFontRef myFont = CTFontCreateWithName((__bridge CFStringRef)([font fontName]), [font pointSize], NULL); 
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text]; 
    [attStr addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)myFont range:NSMakeRange(0, attStr.length)]; 


    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attStr); 

    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathAddRect(path, NULL, CGRectMake(0,0,rect.size.width,100000)); 

    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL); 

    NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame); 
    NSMutableArray *linesArray = [[NSMutableArray alloc]init]; 

    for (id line in lines) 
    { 
     CTLineRef lineRef = (__bridge CTLineRef)line; 
     CFRange lineRange = CTLineGetStringRange(lineRef); 
     NSRange range = NSMakeRange(lineRange.location, lineRange.length); 

     NSString *lineString = [text substringWithRange:range]; 
     [linesArray addObject:lineString]; 
    } 

    return (NSArray *)linesArray; 
} 

を呼び出し、このメソッドを: -

NSArray *linesArray = [self getLinesArrayOfStringInLabel:yourLabel]; 

は今、あなたはlinesArrayを使用することができます。

+0

....率いて....私の時間の多くを保存しました。ありがとう.. –

+0

素晴らしい、素晴らしい。どうもありがとう。 –

5

適切なリリースでの回答!!!!

-(NSArray *)getLinesArrayOfStringInLabel:(UILabel *)label 
{ 
    NSString *text = [label text]; 
    UIFont *font = [label font]; 
    CGRect rect = [label frame]; 

    CTFontRef myFont = CTFontCreateWithName((CFStringRef)([font fontName]), [font pointSize], NULL); 
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text]; 
    [attStr addAttribute:(NSString *)kCTFontAttributeName value:(id)myFont range:NSMakeRange(0, attStr.length)]; 

    CFRelease(myFont); 

    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attStr); 

    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathAddRect(path, NULL, CGRectMake(0,0,rect.size.width,100000)); 

    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL); 

    NSArray *lines = (NSArray *)CTFrameGetLines(frame); 

    NSMutableArray *linesArray = [[NSMutableArray alloc]init]; 

    for (id line in lines) 
    { 
     CTLineRef lineRef = (CTLineRef)line; 
     CFRange lineRange = CTLineGetStringRange(lineRef); 
     NSRange range = NSMakeRange(lineRange.location, lineRange.length); 

     NSString *lineString = [text substringWithRange:range]; 

     CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithFloat:0.0])); 
     CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithInt:0.0])); 

     //NSLog(@"''''''''''''''''''%@",lineString); 
     [linesArray addObject:lineString]; 

    } 
    [attStr release]; 

    CGPathRelease(path); 
    CFRelease(frame); 
    CFRelease(frameSetter); 


    return (NSArray *)linesArray; 
} 
7

スウィフト3

func getLinesArrayFromLabel(label:UILabel) -> [String] { 

     let text:NSString = label.text! as NSString // TODO: Make safe? 
     let font:UIFont = label.font 
     let rect:CGRect = label.frame 

     let myFont:CTFont = CTFontCreateWithName(font.fontName as CFString, font.pointSize, nil) 
     let attStr:NSMutableAttributedString = NSMutableAttributedString(string: text as String) 
     attStr.addAttribute(String(kCTFontAttributeName), value:myFont, range: NSMakeRange(0, attStr.length)) 
     let frameSetter:CTFramesetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString) 
     let path:CGMutablePath = CGMutablePath() 
     path.addRect(CGRect(x:0, y:0, width:rect.size.width, height:100000)) 

     let frame:CTFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil) 
     let lines = CTFrameGetLines(frame) as NSArray 
     var linesArray = [String]() 

     for line in lines { 
      let lineRange = CTLineGetStringRange(line as! CTLine) 
      let range:NSRange = NSMakeRange(lineRange.location, lineRange.length) 
      let lineString = text.substring(with: range) 
      linesArray.append(lineString as String) 
     } 
     return linesArray 
} 

スイフト2(Xcodeの7)バージョン(試験、及びスウィフト1回答から再編集)

func getLinesArrayOfStringInLabel(label:UILabel) -> [String] { 

let text:NSString = label.text! // TODO: Make safe? 
let font:UIFont = label.font 
let rect:CGRect = label.frame 

let myFont:CTFontRef = CTFontCreateWithName(font.fontName, font.pointSize, nil) 
let attStr:NSMutableAttributedString = NSMutableAttributedString(string: text as String) 
attStr.addAttribute(String(kCTFontAttributeName), value:myFont, range: NSMakeRange(0, attStr.length)) 
let frameSetter:CTFramesetterRef = CTFramesetterCreateWithAttributedString(attStr as CFAttributedStringRef) 
let path:CGMutablePathRef = CGPathCreateMutable() 
CGPathAddRect(path, nil, CGRectMake(0, 0, rect.size.width, 100000)) 
let frame:CTFrameRef = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil) 
let lines = CTFrameGetLines(frame) as NSArray 
var linesArray = [String]() 

for line in lines { 
    let lineRange = CTLineGetStringRange(line as! CTLine) 
    let range:NSRange = NSMakeRange(lineRange.location, lineRange.length) 
    let lineString = text.substringWithRange(range) 
    linesArray.append(lineString as String) 
} 
return linesArray 
} 
+1

次のコードを置き換える必要があります ** let text:NSString = label.text! // TODO:安全ですか?** と **ガードレットテキスト:NSString = self.text else { return [] ** –

+4

最初はそれが機能しませんでした。実際の数より多いCGPathAddRect(CGHectMake(0、0、rect.size.width + 15、100000))のCGPathAddRectに変更しました。 と思われます。 – locomotion

+0

これは信頼できません。 https://stackoverflow.com/questions/46923039/get-each-line-of-text-in-a-uilabelを参照してください。 – chicobermuda

1

スイフト3 - Xcodeの8.1

私は以前のXcode 8.1互換のextensionUILabelを作成して、ラベルの最初の行を返します。

import CoreText 

extension UILabel { 

    /// Returns the String displayed in the first line of the UILabel or "" if text or font is missing 
    var firstLineString: String { 

    guard let text = self.text else { return "" } 
    guard let font = self.font else { return "" } 
    let rect = self.frame 

    let attStr = NSMutableAttributedString(string: text) 
    attStr.addAttribute(String(kCTFontAttributeName), value: CTFontCreateWithName(font.fontName as CFString, font.pointSize, nil), range: NSMakeRange(0, attStr.length)) 

    let frameSetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString) 
    let path = CGMutablePath() 
    path.addRect(CGRect(x: 0, y: 0, width: rect.size.width + 7, height: 100)) 
    let frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil) 

    guard let line = (CTFrameGetLines(frame) as! [CTLine]).first else { return "" } 
    let lineString = text[text.startIndex...text.index(text.startIndex, offsetBy: CTLineGetStringRange(line).length-2)] 

    return lineString 
    } 
} 

はそれを使用するには、このようなあなたのUILabelインスタンス上の単純なコールfirstLineString

let firstLine = myLabel.firstLineString 
2

これは、ラベル内のすべての行を取得するためのスウィフト3バージョンがあります。 (@fredpiは同様の答えを持っていますが、それは最初の行のみのためです)素晴らしい答えを

extension UILabel { 

    func getArrayOfLinesInLabel() -> [String] { 

     let text = NSString(string: self.text ?? "-- -- -- --") 
     let font = self.font ?? // Your default font here 
     let rect = self.frame 

     let myFont = CTFontCreateWithName(font.fontName as CFString?, font.pointSize, nil) 
     let attStr = NSMutableAttributedString(string: text as String) 
     attStr.addAttribute(String(kCTFontAttributeName), value:myFont, range: NSRange(location: 0, length: attStr.length)) 
     let frameSetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString) 
     let path = CGPath(rect: CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height), transform: nil) 
     let frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil) 
     guard let lines = CTFrameGetLines(frame) as? [CTLine] else { 
      return [] 
     } 

     var linesArray = [String]() 

     for line in lines { 
      let lineRange = CTLineGetStringRange(line) 
      let range = NSRange(location: lineRange.location, length: lineRange.length) 
      let lineString = text.substring(with: range) 
      linesArray.append(lineString as String) 
     } 

     return linesArray 
    } 
} 
関連する問題