Настройка высоты 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:



проблема была не в этом фрагменте кода, поэтому мое исправление находится в самом вопросе. Это все еще может быть полезно для других!

819   14  

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
}

enter image description here

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

для iOS8 или выше

  • установить ограничение ведущий / трейлинг для вашего UILabel
  • и изменить строки UILabel от 1 до 0

enter image description here

для iOS7

  • первый, вам нужно добавить содержит высоту для UILabel
  • затем изменить отношения с Equal до Greater than or Equal

enter image description here

  • наконец-то измените строки UILabel от 1 до 0

enter image description here

код 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

    Ничего не найдено.