Điều chỉnh chiều cao nhãn thành văn bản


112

Tôi có một số nhãn mà tôi muốn điều chỉnh độ cao của chúng phù hợp với văn bản, đây là mã tôi đã viết cho điều này ngay bây giờ

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
}

BIÊN TẬP:

Vấn đề không nằm trong đoạn mã này, vì vậy cách khắc phục của tôi nằm ở chính câu hỏi. Nó vẫn có thể hữu ích cho những người khác!


Hãy xem các bổ sung của NSString UIKit, có các phương pháp ở đó để tính toán kích thước bạn cần mà không cần tạo UILabel.
Vladimir Gritsenko

@VladimirGritsenko các phương thức 'sizeWithFont' không khả dụng trong Swift :(
TheBurgerShot

Tôi thừa nhận mình không phải là chuyên gia về Swift, nhưng tôi tin rằng bạn có thể thêm các phương pháp bắc cầu của riêng mình. Vẫn có giá trị hơn là tạo UILabel để tính toán kích thước.
Vladimir Gritsenko

@TheBurgerShot sizeWithFontcó thể không khả dụng cho Swift Stringnhưng nó có sẵn trên NSStringBạn vẫn có thể gọi nó trên đó.
Anorak

Cuối cùng, lỗi là một cái gì đó khác nhau và không liên quan gì đến phương pháp này. Mặc dù điều này vẫn có thể hữu ích cho những người khác.
TheBurgerShot

Câu trả lời:


189

Tôi vừa đưa nó vào một sân chơi và nó phù hợp với tôi.

Đã cập nhật cho 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
}

nhập mô tả hình ảnh ở đây


Điều này cũng hoạt động tốt đối với tôi trong sân chơi, lỗi dường như không xảy ra ở vị trí cụ thể này, khi tôi xóa cách sử dụng của phương pháp này, nó sẽ than vãn về một số println hoặc chỉ một dòng chỉ có nhận xét (sau đó nó cho biết mã EXC_BAD_ACCESS = 2)
TheBurgerShot

6
Nó hoạt động trong một sân chơi, nhưng không có kích thước xảy ra như bên trong mong muốn của một bộ điều khiển xem trong XCode 6.1
Unome

1
Tôi hơi do dự khi tạo một UILabelkích thước mới cho mỗi kích thước; nếu phương thức này được sử dụng bên trong layoutSubviewsvới xu hướng được gọi nhiều lần trên mỗi bố cục hoàn chỉnh, thì việc tạo đối tượng bổ sung có thể gây ra sự chậm trễ đáng chú ý, đặc biệt là trong quá trình cuộn.
Zorayr

let textRect = textString.boundsRectWithSize (CGSizeMake (320, 2000), tùy chọn: .UsesLineFragmentOrigin, thuộc tính: textAttributes, context: nil)
Siddharth Pancholi

Tôi không thể gọi chức năng này trong bộ điều khiển chế độ xem của mình ... Bạn có thể gợi ý cho tôi lý do có thể là gì không?
Rouny

64

Nếu bạn đang sử dụng Tự động thanh toán , bạn chỉ có thể điều chỉnh UILabelchiều cao bằng cách cấu hình giao diện người dùng.

Đối với iOS8 trở lên

  • Đặt giới hạn đầu / cuối cho UILabel
  • Và thay đổi các dòng UILabeltừ 1 đến 0

nhập mô tả hình ảnh ở đây

Đối với iOS7

  • Trước tiên , bạn cần thêm chiều cao chứa choUILabel
  • Sau đó , sửa đổi Quan hệ từ EqualthànhGreater than or Equal

nhập mô tả hình ảnh ở đây

  • Cuối cùng , thay đổi các dòng UILabeltừ 1 thành 0

nhập mô tả hình ảnh ở đây

Của bạn UILabelsẽ tự động tăng chiều cao tùy thuộc vào văn bản


2
Và nếu nhãn nằm trong một ô. Bạn sẽ tăng chiều cao ô cho phù hợp khi nào và như thế nào?
oyalhi

1
@oyalhi, nếu nhãn của bạn là bên trong một tế bào tableview, vui lòng xem bài khác của tôi stackoverflow.com/a/36277840/5381331
Phan Văn Linh

3
Điều này làm việc hoàn hảo cho tôi! Thiết lập các ràng buộc và nó sẽ hoạt động bình thường!
Bill Thompson

2
không hiệu quả với tôi ... từ "Nhãn" trong Nhãn UIL làm cho chiều cao = 20. Nó vẫn còn 20 sau cài đặt này.
gadget00

9

Tôi tạo tiện ích mở rộng này nếu bạn muốn

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

8

Tôi có giải pháp làm việc mạnh mẽ.

trong layoutSubviews:

    _title.frame = CGRect(x: 0, y: 0, width: bounds.width, height: 0)
    _title.sizeToFit()
    _title.frame.size = _title.bounds.size

trong trình cài đặt văn bản:

    _title.text = newValue
    setNeedsLayout()

CẬP NHẬT. tất nhiên với cài đặt UILabel này:

    _title.lineBreakMode = .ByWordWrapping
    _title.numberOfLines = 0

6

Chỉ bằng cách thiết lập:

label.numberOfLines = 0

Nhãn tự động điều chỉnh chiều cao của nó dựa trên lượng văn bản được nhập.


27
Điều này không làm cho UILabel điều chỉnh chiều cao của nó.
TheBurgerShot

6

dựa trên câu trả lời của Anorak, tôi cũng đồng ý với mối quan tâm của Zorayr, vì vậy tôi đã thêm một vài dòng để xóa UILabel và chỉ trả lại CGFloat, tôi không biết nó có giúp ích gì không vì mã gốc không thêm UIabel, nhưng nó không gặp lỗi, vì vậy tôi đang sử dụng mã bên dưới:

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

Trong nhanh chóng 4.1 và Xcode 9.4.1

Chỉ 3 bước

Bước 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
}

Bước 2)

//Call this function
let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300)
print(height)//Output : 41.0

Bước 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

Giải pháp được Anorak đề xuất dưới dạng thuộc tính được tính toán trong phần mở rộng cho 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
         }
    }
}

Sử dụng:

self.brandModelLabel.frame.size.height = self.brandModelLabel.optimalHeight

Giải pháp tốt! Cảm ơn bạn :-)
Cristina

Không thể gán cho thuộc tính: 'height' là thuộc tính chỉ nhận.
Amg91

4

Theo sau câu trả lời @Anorak, tôi đã thêm tiện ích mở rộng này vào Chuỗi và gửi nội dung dưới dạng tham số, bởi vì nhiều khi bạn sẽ cần một phần đệm cho văn bản của mình. Dù sao, có thể một số bạn sẽ thấy điều này hữu ích.

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 dòng này đã giúp tôi cảm ơn.
Coder_A_D

3

Đây là cách tính chiều cao văn bản trong Swift. Sau đó, bạn có thể lấy chiều cao từ trực tràng và đặt chiều cao ràng buộc của nhãn hoặc textView, v.v.

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

chỉ cần gọi phương thức này khi bạn cần Chiều cao động cho nhãn

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

Swift 4.0

self.messageLabel = UILabel (frame: CGRect (x: 70, y: 60, width: UIScreen.main.bounds.width - 80, height: 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, áp dụng cho toàn bộ đoạn văn, không áp dụng cho các từ trong đoạn văn. Thuộc tính này có hiệu lực cả trong khi vẽ bình thường và trong các trường hợp phải giảm kích thước phông chữ để vừa với văn bản của nhãn trong hộp giới hạn của nó. Thuộc tính này được đặt thành byTruncatingTail theo mặc định.

Liên kết này mô tả cách làm tương tự của bảng phân cảnh


2
Các câu trả lời chỉ có mã không được coi là thực hành tốt. Vui lòng xem xét thêm một số giải thích về cách câu trả lời của bạn giải quyết câu hỏi.
Yannis

2

Swift 4.0

Thay vì tính toán chiều cao văn bản / nhãn, tôi chỉ thay đổi kích thước nhãn sau khi chèn văn bản (động).

Giả sử rằng myLabel là UILabel được đề cập:

let myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: *somewidth*, height: *placeholder, e.g. 20*))
myLabel.numberOfLines = 0
myLabel.lineBreakMode = .byWordWrapping
...

Và bây giờ đến phần thú vị:

var myLabelText: String = "" {
   didSet {
      myLabel.text = myLabelText
      myLabel.sizeToFit()
   }
}

2

Các Swift 4.1 Phương pháp mở rộng với chiều cao nhãn tính toán:

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 cách phân cảnh. Tôi nghĩ điều này hoạt động cho iOS 9 trở lên. Ví dụ, bạn muốn nhãn "Mô tả" lấy chiều cao động, hãy làm theo các bước:

1) Chọn nhãn mô tả -> Đi tới Trình kiểm tra thuộc tính (biểu tượng bút chì), đặt: Lines: 0 Line Break: Word Wrap

2) Chọn UILabel của bạn từ bảng phân cảnh và đi tới Trình kiểm tra kích thước (biểu tượng thước kẻ), 3) Đi xuống "Mức độ ưu tiên kháng nén nội dung thành 1 cho tất cả các thành phần UIView khác (nhãn, nút, chế độ xem hình ảnh, v.v.) đang tương tác với nhãn của bạn.

Ví dụ: tôi có UIImageView, Title Label và Description Label theo chiều dọc trong chế độ xem của mình. Tôi đặt Mức độ ưu tiên kháng nén nội dung cho UIImageView và nhãn tiêu đề thành 1 và cho nhãn mô tả thành 750. Điều này sẽ làm cho nhãn mô tả có chiều cao cần thiết.


0

Để làm cho nhãn động nhanh chóng, không cung cấp hằng số chiều cao và trong bảng phân cảnh, hãy đặt nhãn số dòng 0 cũng cung cấp giới hạn dưới cùng và đây là cách tốt nhất tôi đang xử lý nhãn động theo kích thước nội dung của chúng.


0

Bạn cũng có thể sử dụng sizeThatFitschức năng.

Ví dụ:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.