Настройка высоты UILabel для текста
У меня есть некоторые метки, которые я хочу настроить их высоту к тексту, это код, который я написал для этого сейчас
func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.font = font
label.text = text
label.sizeToFit()
return label.frame.height
}
EDIT:
проблема была не в этом фрагменте кода, поэтому мое исправление находится в самом вопросе. Это все еще может быть полезно для других!
14 ответов:
Я просто поставлю это на детской площадке, и это работает для меня.
обновлено для Swift 4.0
import UIKit func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{ let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.greatestFiniteMagnitude)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height } let font = UIFont(name: "Helvetica", size: 20.0) var height = heightForView("This is just a load of text", font: font, width: 100.0)Swift 3:
func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{ let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height }
если вы используете AutoLayout, вы можете отрегулировать
UILabelвысота по конфигурациям только пользовательского интерфейса.для iOS8 или выше
- установить ограничение ведущий / трейлинг для вашего
UILabel- и изменить строки
UILabelот 1 до 0для iOS7
- первый, вам нужно добавить содержит высоту для
UILabel- затем изменить отношения с
EqualдоGreater than or Equal
- наконец-то измените строки
UILabelот 1 до 0код
UILabelавтоматически увеличит высоту в зависимости от текста
Я создаю это расширение, если вы хотите
extension UILabel { func setSizeFont (sizeFont: CGFloat) { self.font = UIFont(name: self.font.fontName, size: sizeFont)! self.sizeToFit() } }
только:
label.numberOfLines = 0ярлык автоматически регулирует его высоту в зависимости от количества введенного текста.
у меня есть сильное рабочее решение.
в layoutSubviews:
_title.frame = CGRect(x: 0, y: 0, width: bounds.width, height: 0) _title.sizeToFit() _title.frame.size = _title.bounds.sizeв тексте сеттер:
_title.text = newValue setNeedsLayout()UPD. конечно, с этой настройкой UILabel:
_title.lineBreakMode = .ByWordWrapping _title.numberOfLines = 0
основываясь на ответе Анорака, я также согласен с беспокойством Зорайра, поэтому я добавил пару строк, чтобы удалить UILabel и вернуть только CGFloat, я не знаю, помогает ли это, поскольку исходный код не добавляет UIabel, но он не выдает ошибку, поэтому я использую код ниже:
func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{ var currHeight:CGFloat! let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.ByWordWrapping label.font = font label.text = text label.sizeToFit() currHeight = label.frame.height label.removeFromSuperview() return currHeight }
решение, предложенное анораком в качестве вычисляемого свойства в расширении для UILabel:
extension UILabel { var optimalHeight : CGFloat { get { let label = UILabel(frame: CGRectMake(0, 0, self.frame.width, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = self.lineBreakMode label.font = self.font label.text = self.text label.sizeToFit() return label.frame.height } } }использование:
self.brandModelLabel.frame.size.height = self.brandModelLabel.optimalHeight)
следуя ответу @Anorak, я добавил Это расширение в строку и отправил вставку в качестве параметра, потому что много раз вам понадобится дополнение к вашему тексту. Во всяком случае, может быть, некоторые вы найдете это полезным.
extension String { func heightForWithFont(font: UIFont, width: CGFloat, insets: UIEdgeInsets) -> CGFloat { let label:UILabel = UILabel(frame: CGRectMake(0, 0, width + insets.left + insets.right, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.ByWordWrapping label.font = font label.text = self label.sizeToFit() return label.frame.height + insets.top + insets.bottom } }
вот как рассчитать высоту текста в Swift. Затем вы можете получить высоту из rect и установить высоту ограничения метки или textView и т. д.
let font = UIFont(name: "HelveticaNeue", size: 25)! let text = "This is some really long text just to test how it works for calculating heights in swift of string sizes. What if I add a couple lines of text?" let textString = text as NSString let textAttributes = [NSFontAttributeName: font] let textRect = textString.boundingRectWithSize(CGSizeMake(320, 2000), options: .UsesLineFragmentOrigin, attributes: textAttributes, context: nil)
в swift 4.1 и Xcode 9.4.1
только 3 шага
Шаг 1)
//To calculate height for label based on text size and width func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat { let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height }Шаг 2)
//Call this function let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300) print(height)//Output : 41.0Шаг 3)
//This is your label let proNameLbl = UILabel(frame: CGRect(x: 0, y: 20, width: 300, height: height)) proNameLbl.text = "This is your text" proNameLbl.font = UIFont.systemFont(ofSize: 17) proNameLbl.numberOfLines = 0 proNameLbl.lineBreakMode = .byWordWrapping infoView.addSubview(proNameLbl)
просто вызовите этот метод, где вам нужна динамическая высота для метки
func getHeightforController(view: AnyObject) -> CGFloat { let tempView: UILabel = view as! UILabel var context: NSStringDrawingContext = NSStringDrawingContext() context.minimumScaleFactor = 0.8 var width: CGFloat = tempView.frame.size.width width = ((UIScreen.mainScreen().bounds.width)/320)*width let size: CGSize = tempView.text!.boundingRectWithSize(CGSizeMake(width, 2000), options:NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: tempView.font], context: context).size as CGSize return size.height }
Swift 4.0
self.messageLabel = UILabel (кадр: CGRect (x: 70, y:60, ширина: UIScreen.главный.границы.ширина - 80, высота: 30)
messageLabel.text = message messageLabel.lineBreakMode = .byWordWrapping //in versions below swift 3 (messageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping) messageLabel.numberOfLines = 0 //To write any number of lines within a label scope messageLabel.textAlignment = .center messageLabel.textColor = UIColor.white messageLabel.font = messageLabel.font.withSize(12) messageLabel.sizeToFit()Blockquote NSParagraphStyle.LineBreakMode, применяется ко всем абзацам, а не к словам внутри абзацев.Это свойство действует как во время обычного рисования, так и в тех случаях, когда размер шрифта должен быть уменьшен, чтобы соответствовать тексту метки в его ограничительной рамке. Это свойство имеет значение byTruncatingTail by по умолчанию.
Swift 4.0
вместо вычисления высоты текста / метки я просто изменяю размер метки после вставки (динамического) текста.
предполагая, что myLabel является UILabel в вопросе:
let myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: *somewidth*, height: *placeholder, e.g. 20*)) myLabel.numberOfLines = 0 myLabel.lineBreakMode = .byWordWrapping ...а теперь самое интересное:
var myLabelText: String = "" { didSet { myLabel.text = myLabelText myLabel.sizeToFit() } }
на Swift 4.1 метод расширения для вычисления высоты метки:
extension UILabel { func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat { let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.byWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height } }



Comments