UILabel 높이를 텍스트로 조정


112

텍스트에 맞게 높이를 조정하려는 레이블이 있습니다. 이것이 제가 지금 작성한 코드입니다.

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
}

편집하다:

문제는이 코드 부분이 아니므로 내 수정 사항은 문제 자체에 있습니다. 다른 사람들에게 여전히 유용 할 수 있습니다!


NSString UIKit 추가를 살펴보면 UILabel을 만들지 않고도 필요에 따라 크기를 계산할 수있는 방법이 있습니다.
Vladimir Gritsenko 2014 년

@VladimirGritsenko는 'sizeWithFont'방법 :( 스위프트에 사용할 수 없습니다
TheBurgerShot

제가 Swift의 전문가는 아니지만 자신 만의 브리징 방법을 추가 할 수 있다고 믿습니다. 크기를 계산하기 위해 UILabel을 만드는 것보다 여전히 가치가 있습니다.
Vladimir Gritsenko 2014 년

@TheBurgerShot sizeWithFont은 Swift에서 사용 가능하지 않을 수 String있지만 사용할 수 있습니다. NSString여전히 호출 할 수 있습니다.
Anorak

결국 오류는 다른 것이었고이 방법과 관련이 없습니다. 이것은 여전히 ​​다른 사람들에게 도움이 될 수 있습니다.
TheBurgerShot 2015 년

답변:


189

나는 이것을 놀이터에 두었고 그것은 나를 위해 작동합니다.

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)

스위프트 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
}

여기에 이미지 설명 입력


이것은 놀이터에서 나에게도 잘 작동합니다.이 특정 장소에서 오류가 발생하지 않는 것 같습니다.이 방법의 사용법을 제거하면 일부 println 또는 주석 만있는 줄에 대해 우는 소리가납니다 (그런 다음 EXC_BAD_ACCESS code = 2도)
TheBurgerShot 2014-08-08

6
놀이터에서 작동하지만 XCode 6.1의 뷰 컨트롤러 내부에서 원하는대로 크기가 조정되지 않습니다
Unome

1
나는 UILabel크기별로 새로운 것을 만드는 것을 조금 주저합니다 . 이 메서드가 layoutSubviews전체 레이아웃 당 여러 번 호출되는 경향이있는 내부 에서 사용되는 경우 추가 개체 생성으로 인해 특히 스크롤 중에 눈에 띄는 지연이 발생할 수 있습니다.
Zorayr

textRect = textString.boundingRectWithSize하자 (CGSizeMake (320, 2000), 옵션 : .UsesLineFragmentOrigin를, 속성 : TextAttribute가, 컨텍스트 : 무기 호)
싯다 르트 나라 얀 Pancholi

뷰 컨트롤러에서이 함수를 호출 할 수 없습니다. 가능한 이유가 무엇인지 제안 해 주시겠습니까?
Rouny

64

AutoLayout을 사용하는 경우UILabel 구성 UI로만 높이를 조정할 수 있습니다 .

iOS8 이상

  • 제약 조건 선행 / 후행 설정 UILabel
  • 그리고 줄을 UILabel1에서 0으로 변경하십시오.

여기에 이미지 설명 입력

iOS7의 경우

  • 먼저 , 포함 높이를 추가해야합니다.UILabel
  • 그런 다음 Relation from Equalto toGreater than or Equal

여기에 이미지 설명 입력

  • 마지막으로 행을 UILabel1에서 0 으로 변경합니다.

여기에 이미지 설명 입력

당신의 UILabel의지는 자동으로 텍스트에 따라 높이를 증가


2
그리고 라벨이 셀 안에 있다면. 그에 따라 셀 높이를 언제 어떻게 늘릴 것인가?
oyalhi

1
@oyalhi, 레이블이 tableview 셀 내부에 있으면 다른 게시물 stackoverflow.com/a/36277840/5381331
Phan Van Linh

3
이것은 나를 위해 완벽하게 작동했습니다! 제약 조건을 설정하면 제대로 작동합니다!
Bill Thompson

2
나를 위해 작동하지 않습니다 ... UILabel의 "Label"이라는 단어는 height = 20을 만듭니다. 이 설정 이후에는 20 개가 유지됩니다.
gadget00

9

원하는 경우이 확장 프로그램을 만듭니다.

extension UILabel {
    func setSizeFont (sizeFont: CGFloat) {
        self.font =  UIFont(name: self.font.fontName, size: sizeFont)!
        self.sizeToFit()
    }
}

8

강력한 작업 솔루션이 있습니다.

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

6

설정하기 만하면 :

label.numberOfLines = 0

레이블은 입력 한 텍스트 양에 따라 높이를 자동으로 조정합니다.


27
이것은 높이를 조정하는 UILabel을 만들지 않습니다.
TheBurgerShot

6

Anorak의 답변에 따라 Zorayr의 우려에도 동의하므로 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
}

5

신속한 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)

5

Anorak이 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

좋은 해결책! 감사합니다 :-)
Cristina

속성에 할당 할 수 없음 : 'height'는 가져 오기 전용 속성입니다.
Amg91

4

@Anorak 답변에 따라이 확장을 String에 추가하고 매개 변수로 삽입을 보냈습니다. 많은 경우 텍스트에 패딩이 필요하기 때문입니다. 어쨌든, 아마도 당신은 이것이 유용하다는 것을 알게 될 것입니다.

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

label.lineBreakMode = NSLineBreakMode.ByWordWrapping이 줄이 도움이되었습니다.
Coder_A_D

3

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)

3

레이블에 대한 동적 높이가 필요한 곳에서이 메서드를 호출하면됩니다.

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
}

3

스위프트 4.0

self.messageLabel = UILabel (프레임 : CGRect (x : 70, y : 60, 너비 : UIScreen.main.bounds.width-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로 설정됩니다.

이 링크는 동일한 작업을 수행하는 스토리 보드 방식을 설명합니다.


2
코드 전용 답변은 모범 사례로 간주되지 않습니다. 귀하의 답변이 질문을 어떻게 해결하는지에 대한 설명을 추가해보십시오.
Yannis

2

스위프트 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()
   }
}

2

라벨 높이를 계산 하는 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
    }

}

1

Swift 5, XCode 11 스토리 보드 방식. iOS 9 이상에서 작동한다고 생각합니다. 예를 들어 "설명"레이블을 사용하여 동적 높이를 얻으려면 다음 단계를 따르십시오.

1) 설명 레이블 선택-> 속성 검사기 (연필 아이콘)로 이동, 설정 : 줄 : 0 줄 바꿈 : 단어 줄 바꿈

2) 스토리 보드에서 UILabel을 선택하고 Size Inspector (눈금자 아이콘)로 이동합니다. 3) 레이블과 상호 작용하는 다른 모든 UIView (레이블, 버튼, 이미지보기 등) 구성 요소에 대해 "Content Compression Resistance Priority to 1로 이동합니다.

예를 들어, 뷰에 UIImageView, 제목 레이블 및 설명 레이블이 세로로 있습니다. Content Compression Resistance Priority를 ​​UIImageView로 설정하고 제목 레이블을 1로 설정하고 설명 레이블을 750으로 설정합니다. 이렇게하면 설명 레이블이 필요한 높이만큼 많이 차지하게됩니다.


0

신속하게 레이블을 동적으로 만들려면 높이를 constarint로 지정하지 말고 스토리 보드에서 줄 번호 0도 하단 제약 조건을 제공하며 이것이 콘텐츠 크기에 따라 동적 레이블을 처리하는 가장 좋은 방법입니다.


0

sizeThatFits기능 을 사용할 수도 있습니다 .

예를 들면 :

label.sizeThatFits(superView.frame.size).height

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.