Как получить текст из n-й строки UILabel?

Есть ли простой способ получить (или просто отобразить) текст из заданной строки в UILabel?

Мой UILabel правильно отображает мой текст и красиво оформляет его, но иногда мне нужно просто показывать определенные строки, но, очевидно, мне нужно знать, как UILabel позиционирует все для этого.

Я знаю, что это легко можно сделать с помощью подстроки, но мне нужно знать начальную и конечную точки линии.

В качестве альтернативы я мог прокручивать UILabel, если было какое-то смещение к кадру UILabel и скрыть остальную часть содержимого, которое я не хотел видеть.

Я не смог раскрыть что-либо, что показывает, как это можно сделать легко. У кого-нибудь есть хорошие идеи?

благодаря

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++; } } 

Если высота изменяется, это означает, что перед словом происходит разрыв строки.
Я не могу проверить правильность написания синтаксиса сейчас, поэтому вам нужно проверить это самостоятельно.

У меня есть лучший способ найти его.

Вы можете получить это с помощью CoreText.framework .

1.Add CoreText.framework .
2.Import #import .
Затем используйте метод ниже:

 - (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 .

SWIFT 4 VERSION

 func getLinesArrayOfString(in label: UILabel) -> [String] { /// An empty string's array var linesArray = [String]() guard let text = label.text, let font = label.font else {return linesArray} let rect = label.frame let myFont: CTFont = CTFontCreateWithName(font.fontName as CFString, font.pointSize, nil) let attStr = NSMutableAttributedString(string: text) attStr.addAttribute(kCTFontAttributeName as NSAttributedStringKey, value: myFont, range: NSRange(location: 0, length: 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), transform: .identity) let frame: CTFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil) guard let lines = CTFrameGetLines(frame) as? [Any] else {return linesArray} for line in lines { let lineRef = line as! CTLine let lineRange: CFRange = CTLineGetStringRange(lineRef) let range = NSRange(location: lineRange.location, length: lineRange.length) let lineString: String = (text as NSString).substring(with: range) linesArray.append(lineString) } return linesArray } 

Использование:

 let lines: [String] = getLinesArrayOfString(in: label) 

Swift 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 } 

Версия Swift 2 (Xcode 7) (протестирована и отредактирована с помощью ответа Swift 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 } 

Ответ на правильный выпуск !!!!

 -(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; } 

Это версия Swift 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 } } 

Swift 3 – Xcode 8.1

Я собрал код из предыдущих ответов, чтобы создать extension SWIFT 3, Xcode 8.1, чтобы UILabel вернул первую строку метки.

 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 } } 

Чтобы использовать его, просто вызовите firstLineString в вашем экземпляре UILabel например:

 let firstLine = myLabel.firstLineString 

Если все ваши символы отображаются одинакового размера, то есть они заключены в коробку с общим размером, вы можете воспользоваться этим. (Например, это похоже на японские символы).

В противном случае вы можете запросить размер каждого символа в шрифте дисплея и рассчитать, какая строка должна быть.

Единственное беспокойство в том, что ваш расчет может не совпадать с тем, что Apple делает за кулисами, и в этом случае я рекомендую вам перейти к переопределению чертежа текстового фрейма. Посмотрите на основной текст в документах для этого.

(Возможно, я делал это неправильно, но я не нашел, что метод Apple, приведенный в документах, был очень точным, поэтому я сделал что-то еще.)

  • Обработка события Touch в UILabel и подключение его к IBAction
  • Как отрегулировать размер шрифта метки для соответствия прямоугольнику?
  • Динамическое обновление UILabel
  • UILabel и NSLinkAttributeName: ссылка не доступна для кликов
  • Как управлять расстоянием между строками в UILabel
  • Как сделать UILabel доступным?
  • Почему UINavigationBar крадет события касания?
  • UINavigationBar многострочное название
  • Как установить жирный шрифт и курсив на UILabel iPhone / iPad?
  • objective C: Как вы можете повернуть текст для UIButton и UILabel?
  • iPhone - UILabel, содержащий текст с несколькими шрифтами одновременно
  • Давайте будем гением компьютера.