Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> iOS

วิธีให้ UILabel มีความสูงแบบไดนามิก (Dynamic Height) ใน Swift

ทำให้ UILabel ขยายความสูงตามเนื้อหา ใช้ Auto Layout + numberOfLines = 0

หลักการสำคัญ

  1. numberOfLines = 0 (Unlimited Lines)
  2. Constraints: Top, Leading, Trailing, Bottom (หรือ Height ≥)
  3. ไม่ตั้ง Height Constraint คงที่
  4. Content Hugging/Compression Resistance Priority เหมาะสม

โค้ดตัวอย่าง


let label = UILabel()
label.numberOfLines = 0
label.font = .systemFont(ofSize: 16)
label.textColor = .label
label.text = "Long text that wraps to multiple lines automatically based on the width constraint."
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)

NSLayoutConstraint.activate([
    label.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
    label.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
    label.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
    // Bottom Constraint ทำให้ Label ขยายได้
    label.bottomAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20)
])

// Priority ป้องกันบีบอัด
label.setContentCompressionResistancePriority(.required, for: .vertical)
label.setContentHuggingPriority(.defaultHigh, for: .vertical)

ใน Table View Cell (Self-Sizing Cells)


// TableView Setup
tableView.estimatedRowHeight = 44
tableView.rowHeight = UITableView.automaticDimension

// Cell: Label ต้องมี Top/Bottom Constraint ถึง ContentView
// numberOfLines = 0

คำนวณความสูงด้วยโค้ด (Manual)


func heightForLabel(text: String, font: UIFont, width: CGFloat) -> CGFloat {
    let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
    let boundingBox = text.boundingRect(with: constraintRect, 
                                         options: [.usesLineFragmentOrigin, .usesFontLeading],
                                         attributes: [.font: font], 
                                         context: nil)
    return ceil(boundingBox.height)
}

// ใช้งาน
let height = heightForLabel(text: longText, font: .systemFont(ofSize: 16), width: 300)

Storyboard

  1. Label → Attributes Inspector → Lines = 0
  2. Constraints: Top, Leading, Trailing, Bottom (to Container)
  3. Size Inspector → Content Hugging Priority (Vertical) = 251 (High)

Dynamic Type Support


label.adjustsFontForContentSizeCategory = true
label.font = .preferredFont(forTextStyle: .body)
// ข้อความจะขยายตาม Text Size ที่ User ตั้งใน Settings

SwiftUI


Text("Dynamic height text that wraps automatically based on content and width.")
    .font(.body)
    .frame(maxWidth: .infinity, alignment: .leading)
// ไม่ต้องตั้งอะไร Auto Layout ทำให้อัตโนมัติ