Dynamic Type: แนวคิดหลัก รูปแบบข้อความ และการทำงานใน iOS

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-05-16 เวลาอ่าน: 9 นาที

Dynamic Type เป็นฟีเจอร์ที่ติดตั้งมาใน iOS ที่เปลี่ยนขนาดแบบอักษรในแอปโดยอัตโนมัติตามการตั้งค่าระบบของผู้ใช้ ผู้ใช้กำหนดขนาดข้อความที่ต้องการใน Settings → Display & Brightness → Text Size และแอปทั้งหมดที่รองรับ Dynamic Type จะปรับตัวโดยไม่ต้องมีการกระทำเพิ่มเติม ตาม Apple Human Interface Guidelines, 2024 การรองรับ Dynamic Type เป็นข้อกำหนดที่จำเป็นสำหรับการเผยแพร่ใน App Store เนื่องจากเป็น องค์ประกอบพื้นฐาน ของการเข้าถึงได้บนแพลตฟอร์ม iOS

สาระสำคัญ

  • Dynamic Type — กลไก iOS สำหรับการปรับขนาดข้อความโดยอัตโนมัติตามการตั้งค่าขนาดแบบอักษรของระบบ
  • การรองรับจัดให้ผ่าน รูปแบบข้อความ (UIFont.TextStyle) — body, headline, caption, title และอื่นๆ
  • ระบบรองรับ 11 ระดับ การปรับขนาดตั้งแต่ XSmall ถึง AccessibilityXXXL
  • สำหรับแบบอักษรที่กำหนดเองใช้วิธีการ UIFontMetrics ซึ่งปรับขนาดแบบอักษรใดๆเทียบกับรูปแบบ body
  • เลย์เอาต์ต้อง ปรับตัวได้ — UIStackView, Auto Layout และความสูงแบบไดนามิกของเซลล์เป็นสิ่งจำเป็น

Dynamic Type ใน iOS คืออะไร

Dynamic Type เป็นเทคโนโลยีของ iOS ที่เปิดตัวใน iOS 7 ซึ่งทำให้ข้อความในแอปปรับตัวไปยังการตั้งค่าขนาดแบบอักษรของระบบโดยอัตโนมัติ ผู้ใช้สามารถเพิ่มหรือลดแบบอักษรในทุกแอพพร้อมกันได้ — โดยไม่ต้องเปลี่ยนการตั้งค่าภายในแต่ละแอพพ์แยกกัน

ตาม Apple WWDC 2023, “Make Your App Visually Accessible” ผู้ใช้ iOS มากกว่า 40% เปลี่ยนขนาดแบบอักษรจากค่าเริ่มต้น สำหรับกลุ่มอายุ 65+ ตัวเลขนี้สูงถึง 70% Dynamic Type เป็นข้อกำหนดที่จำเป็นสำหรับการรับรองการเข้าถึงได้ของ App Store การขาดการรองรับเป็นสาเหตุในการปฏิเสธแอพระหว่างการตรวจสอบ

หลักการทำงาน: แอพใช้ UIFont.preferredFont(forTextStyle:) แทน UIFont(name:size:) iOS จะส่งคืนแบบอักษรที่ปรับขนาดแล้วตามการตั้งค่าระบบปัจจุบันโดยอัตโนมัติ เมื่อขนาดเปลี่ยนไปในการตั้งค่า iOS จะสร้าง UIContentSizeCategory.didChangeNotification — แอพต้องคำนวณเลย์เอาต์ใหม่

ประวัติของ Dynamic Type

Dynamic Type เปิดตัวใน iOS 7 พร้อมกับดีไซน์เรียบ iOS 10 เพิ่มการรองรับแบบอักษรที่กำหนดเองผ่าน UIFontMetrics iOS 11 แนะนำระดับการเข้าถึงได้ (ถึง AccessibilityXXXL) iOS 15 เพิ่ม Dynamic Type ใน SwiftUI ด้วยการรองรับอัตโนมัติ ทุกรุ่นที่เผยแพร่ Apple เพิ่มความเข้มงวด: ตั้งแต่ iOS 17 เป็นต้นไป แอพที่ไม่มีการรองรับ Dynamic Type จะได้รับ คำเตือน เมื่ออัปโหลดไปยัง App Store Connect

รูปแบบข้อความ UIFont.TextStyle

iOS มี 8 รูปแบบข้อความ แต่ละแบบมีขนาดและความหนาที่กำหนดไว้ล่วงหน้าสำหรับการตั้งค่าเริ่มต้น:

รูปแบบค่าคงที่ขนาด (L)วัตถุประสงค์
Large Title.largeTitle34pxชื่อเรื่องหลักของหน้าจอ
Title 1.title128pxหัวข้อส่วน
Title 2.title222pxหัวข้อย่อย
Title 3.title320pxชื่อเรื่องของการ์ด
Headline.headline17px (ตัวหนา)ตัวหนาสำหรับเน้น
Body.body17pxข้อความหลัก
Callout.callout16pxข้อความเสริม
Caption 1.caption112pxคำอธิบายภาพ
Caption 2.caption211pxคำอธิบายขนาดเล็ก
Footnote.footnote13pxเชิงอรรถ, หมายเหตุ

การใช้รูปแบบที่ถูกต้องไม่ใช่แค่เรื่องของ “รูปลักษณ์ภายนอก” UIFont.TextStyle.body ในโหมด AccessibilityXXXL สามารถสูงถึง 53px หากแอพใช้แบบอักษรตามปกติ 17px สำหรับ body ข้อความจะไม่สามารถอ่านได้สำหรับผู้ใช้ที่เพิ่มขนาดแบบอักษร

ลำดับชั้นเส้นทางสายตาผ่านรูปแบบ

Dynamic Type ไม่ได้แค่ปรับขนาด — แต่ยังคงรักษา ลำดับชั้นเส้นทางสายตา Large Title ใหญ่กว่า Title 1 เสมอ และ Title 1 ใหญ่กว่า Body โดยไม่ขึ้นกับระดับการปรับขนาด ค่าสัมประสิทธิ์การปรับขนาดแตกต่างกัน: หัวข้อจะปรับขนาดรุนแรงกว่าข้อความหลัก เพื่อให้ลำดับชั้นยังคงอยู่แม้ในระดับการเข้าถึงได้

ระดับการปรับขนาด

iOS รองรับ 11 ระดับ การปรับขนาดข้อความ แบ่งออกเป็นสองหมวดหมู่:

  • ขนาดมาตรฐาน (5 ระดับ): XS, S, M, L (ค่าเริ่มต้น), XL
  • ขนาดการเข้าถึงได้ (6 ระดับ): accessibilityXL, accessibilityXXL, accessibilityXXXL, accessibilityXXXXL, accessibilityXXXXXL, accessibilityXXXXXXL

ความแตกต่างระหว่าง XS และ AccessibilityXXXL สำหรับรูปแบบ body อยู่ที่ 14px ถึง 53px — เกือบ 4 เท่า เลย์เอาต์ที่ออกแบบมาสำหรับ 17px จะพังโดยสิ้นเชิ้งที่ 53px: ข้อความล้นเฮือมพันเขต, ปุ่มทับซ้อนกัน, เซลล์ชนกัน

ตรวจสอบหมวดหมู่ปัจจุบันในโค้ด:

swift
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
    // เปิดใช้งานเลย์เอาต์ทางเลือก
}

traitCollection และขนาดข้อความ

หมวดหมู่ขนาดข้อความสามารถเข้าถึงได้ผ่าน traitCollection.uiContentSizeCategory เมื่อการตั้งค่าระบบเปลี่ยนไป iOS จะเรียก traitCollectionDidChange บน UIView ทั้งหมด ในมีเทอดนี้ คุณต้องอัพเดตแบบอักษรและคำนวณเลย์เอาต์ใหม่ SwiftUI ทำสิ่งนี้โดยอัตโนมัติ — UIKit ต้องการสมัครด้วยตนเอง

สำหรับ UICollectionView ใช้ UICollectionViewCompositionalLayout — จะปรับจำนวนคอลัมน์โดยอัตโนมัติตามความกว้างหน้าจอและขนาดข้อความ ในระดับการเข้าถึงได้ ให้เปลี่ยนจากเลย์เอาต์สองคอลัมน์เป็นเลย์เอาต์คอลัมน์เดียว เพื่อไม่ให้ข้อความถูกตัดและองค์ประกอบไม่ซ้อนกัน ใช้เลย์เอาต์แบบมีเงื่อนไข: สำหรับ regular width — สองคอลัมน์, สำหรับ compact หรือ accessibility — หนึ่งคอลัมน์

การนำไปใช้ใน UIKit

การนำไปใช้ขั้นพื้นฐานใน UIKit — UIFont.preferredFont(forTextStyle:) เมทอดนี้จะส่งคืนแบบอักษรที่ปรับขนาดแล้วตามการตั้งค่าระบบปัจจุบัน:

swift
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)

สำหรับ แบบอักษรที่กำหนดเอง ใช้ UIFontMetrics:

swift
let customFont = UIFont(name: "Montserrat-Regular", size: 16)!
titleLabel.font = UIFontMetrics(forTextStyle: .body)
    .scaledFont(for: customFont)

// ติดตามการเปลี่ยนแปลงขนาด
NotificationCenter.default.addObserver(
    self,
    selector: #selector(preferredContentSizeChanged),
    name: UIContentSizeCategory.didChangeNotification,
    object: nil
)

สำหรับ UILabel ใน Interface Builder แค่ตั้งแบบอักษรเป็นรูปแบบข้อความ (Text Style) และเปิดใช้งาน “Automatically Adjusts Font” สำหรับแบบอักษรที่กำหนดเอง Interface Builder ไม่รองรับ UIFontMetrics — ผ่านโค้ดเท่านั้น

UIFontMetrics และเส้นโค้งการปรับขนาด

UIFontMetrics ใช้เส้นโค้งการปรับขนาดเดียวกับ preferredFont คุณสามารถระบุ fromTextStyle: .body, .headline ได้ แต่ละรูปแบบมีค่าสัมประสิทธิ์การปรับขนาดของตนเอง Body ปรับขนาดปานกลาง, Large Title ปรับขนาดอย่างรุนแรง หากแบบอักษรที่กำหนดเองของคุณถูกใช้สำหรับข้อความหลัก ใช้ .body

Dynamic Type ใน SwiftUI

ใน SwiftUI การรองรับ Dynamic Type ถูกติดตั้งมาตั้งแต่ต้น ตัวปรับแต่งระบบทั้งหมด (.font(.body), .font(.title)) จะปรับขนาดโดยอัตโนมัติ นักพัฒนาไม่จำเป็นต้องเรียก UIFont.preferredFont

ตัวอย่าง:

swift
Text("ข้อความหลัก")
    .font(.body)
    .lineLimit(nil)
    .minimumScaleFactor(0.5)

สำหรับ การปรับขนาดแบบกำหนดเอง ใช้ DynamicTypeSize:

swift
@Environment(\.dynamicTypeSize) var dynamicTypeSize

var body: some View {
    Text("ข้อความแบบปรับตัวได้")
        .font(.body)
        .padding(dynamicTypeSize <= .large ? 8 : 16)
}

SwiftUI จะอัพเดตมุมมองโดยอัตโนมัติเมื่อขนาดข้อความระบบเปลี่ยนไป — ไม่ต้องมีการสมัครรับข้อความเพิ่มเติม

ข้อจำกัด Dynamic Type ใน SwiftUI

ตัวปรับแต่ง .font(.body) ทำงานเฉพาะกับแบบอักษรระบบเท่านั้น สำหรับแบบอักษรที่กำหนดเองใน SwiftUI ใช้ Font.custom กับ UIFontMetrics เบื้องหลัง ตั้งแต่ iOS 16 SwiftUI รองรับ DynamicTypeSize ใน @Environment ซึ่งทำให้สามารถปรับรูปแบบรองรับและเลย์เอาต์ได้

การปรับเนื่อไลห์สำหรับแบบอักษรขนาดใหญ่

Auto Layout เป็นเงื่อนไขที่จำเป็นสำหรับการรองรับ Dynamic Type ความกว้างและความสูงตามเชิง (>=, <=) จะพังในขนาดการเข้าถึงได้ ใช้ intrinsicContentSize สำหรับ UILabel — จะคำนวณความสูงโดยอัตโนมัติสำหรับขนาดแบบอักษรปัจจุบัน

กฎของเลย์เอาต์แบบปรับตัวได้:

  • UIStackView ด้วย distribution = fill และ spacing >= 8 — องค์ประกอบจะถูกย้ายไปยังแถวถัดไป
  • UITableViewCell ด้วย automaticDimension — ความสูงของเซลล์จะปรับตามเนื้อหา
  • numberOfLines = 0 บน UILabel — ข้อความจะไม่ถูกตัด แต่จะถูกตัดคำแบ่งบทเพื่อให้ข้อความขึ้นบรรทัดใหม่
  • ปุ่มด้วย edgeInsets — เพิ่มรองรับในระดับการเข้าถึงได้ผ่าน traitCollection.preferredContentSizeCategory

สำหรับข้อความยาว (เช่น บทความ, เงื่อนไขการใช้งาน) ให้ตั้ง minimumScaleFactor บน UILabel — นี้จะลดข้อความเป็นตัวเลือกสุดท้ายเมื่อ Auto Layout ไม่สามารถรองรับเนื้อหาได้ ค่า 0.5 หมายความว่าแบบอักษรสามารถลดขนาดได้ถึง 50% ของขนาดที่ต้องการ

ตัวอย่างการปรับรองรับตามหมวดหมู่ขนาด:

swift
let isAccessibility = traitCollection
    .preferredContentSizeCategory.isAccessibilityCategory
stackView.spacing = isAccessibility ? 16 : 8
button.contentEdgeInsets = isAccessibility
    ? UIEdgeInsets(top: 16, left: 24, bottom: 16, right: 24)
    : UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)

ปัญหาเลย์เอาต์ทั่วไปในระดับการเข้าถึงได้

การตัดข้อความ — UILabel ด้วย numberOfLines = 1 และความกว้างตามปกติจะตัดข้อความใน AccessibilityXL วิธีแก้: numberOfLines = 0 และข้อจำกัด trailing การซ้อนกันขององค์ประกอบ — ปุ่มที่มีความสูงตามปกติจะซ้อนกัน วิธีแก้: UIStackView ด้วยการวงระยะอัตโนมัติ เนื้อหาออกนอกหน้าจอ — ScrollView เป็นสิ่งจำเป็นสำหรับระดับการเข้าถึงได้

การทดสอบ Dynamic Type

Xcode Simulator ช่วยให้เปลี่ยนขนาดข้อความได้: ในเมนูจำลองไปที่ Settings → Accessibility → Display & Text Size → Larger Text สลับระหว่งทุก 11 ระดับและตรวจสอบว่าข้อความไม่ถูกตัด, ปุ่มสามารถเข้าถึงได้, และเลย์เอาต์ไม่พัง

สำหรับ การทดสอบอัตโนมัติ ใช้การตั้งค่า contentSizeCategory ใน XCUIApplication:

swift
func testAccessibilitySizes() {
    let app = XCUIApplication()
    app.launchArguments += [
        "-UIPreferredContentSizeCategoryName",
        "UICTContentSizeCategoryAccessibilityXXXL"
    ]
    app.launch()
    app.scrollViews.buttons["ส่ง"].tap()
    XCTAssertTrue(app.staticTexts["ส่งแบบฟอร์มแล้ว"]
        .waitForExistence(timeout: 5))
}

XCUITest ด้วย launchArguments ที่แตกต่างกันช่วยให้ตรวจสอบทุกระดับการปรับขนาดใน CI อย่าลืมทดสอบหมวดหมู่การเข้าถึงได้แยกต่างหาก — เพราะมักทำให้เลย์เอาต์พัง ตามข้อมูลจาก Apple, 70% ของข้อผิดพลาด Dynamic Type ถูกพบในระดับการเข้าถึงได้ เพราะนักพัฒนามักทดสอบเฉพาะขนาดมาตรฐาน

Accessibility Inspector: การตรวจสอบ Dynamic Type

Xcode Accessibility Inspector แสดงว่าองค์ประกอบที่เลือกใช้แบบอักษรชนิดใด — ตามปกติหรือปรับขนาดได้ หากองค์ประกอบไม่ตอบสนองต่อการเปลี่ยนขนาดข้อความในจำลอง แสดงว่ากำลังใช้แบบอักษรตามปกติ ให้แทนที่ด้วย UIFont.preferredFont หรือ UIFontMetrics

คำถามที่พบบ่อย

Dynamic Type ใน iOS คืออะไรในคำพูดง่ายๆ?

มันคือการ ปรับขนาดข้อความโดยอัตโนมัติ ในแอพตามการตั้งค่าขนาดของระบบ ผู้ใช้เปลี่ยนขนาดใน Settings — แอพที่รองรับทั้งหมดจะปรับตัวโดยไม่ต้องให้นักพัฒนาเข้ามาเกี่ยวข้อง

Dynamic Type ทำงานเฉพาะกับแบบอักษรระบบหรือไม่?

ไม่ สำหรับ แบบอักษรที่กำหนดเอง ใช้ UIFontMetrics(scaledFont:) เมทอดนี้จะปรับขนาดแบบอักษรใดๆเทียบกับรูปแบบข้อความที่ระบุ โดยรักษาสัดส่วนไว้

iOS รองรับกี่ระดับการปรับขนาด?

11 ระดับ: 5 ระดับมาตรฐาน (XS, S, M, L, XL) และ 6 ระดับการเข้าถึงได้ (จาก AccessibilityXL ถึง AccessibilityXXXXXL) ขนาดแบบอักษร body สามารถอยู่ระหว่าง 14px ถึง 53px

จะสมัครรับการเปลี่ยนแปลงขนาดข้อความได้อย่างไร?

ใน UIKit ผ่าน UIContentSizeCategory.didChangeNotification ใน SwiftUI ใช้ @Environment(\.dynamicTypeSize) — มุมมองจะอัพเดตโดยอัตโนมัติเมื่อการตั้งค่าระบบเปลี่ยนไป

จะเกิดอะไรขึ้นหากไม่รองรับ Dynamic Type?

ผู้ใช้ที่มีขนาดแบบอักษรใหญ่ขึ้นจะเห็น ข้อความที่ถูกตัด, องค์ประกอบที่ซ้อนกัน และปุ่มที่ใช้งานไม่ได้ แอพอาชugถูกปฏิเสธในการตรวจสอบ App Store เนื่องจากละเมิดข้อกำหนดการเข้าถึงได้

สรุป

  • Dynamic Type — กลไกในตัวของ iOS สำหรับปรับขนาดข้อความตามการตั้งค่าระบบ; จำเป็นสำหรับ App Store
  • ใช้ UIFont.preferredFont(forTextStyle:) สำหรับแบบอักษรระบบและ UIFontMetrics สำหรับแบบอักษรที่กำหนดเอง
  • iOS รองรับ 11 ระดับ การปรับขนาด — จาก XS ถึง AccessibilityXXXXXL (14–53px สำหรับ body)
  • ใน SwiftUI Dynamic Type ทำงาน โดยอัตโนมัติ ผ่าน .font(.body) และ @Environment(\.dynamicTypeSize)
  • เลย์เอาต์ต้อง ปรับตัวได้: UIStackView, automaticDimension ในตาราง, numberOfLines = 0
  • ทดสอบทั้ง 11 ระดับ, โดยเฉพาะ หมวดหมู่การเข้าถึงได้ — 70% ของเลย์เอาต์พังในระดับเหล่านี้
  • การสมัคร UIContentSizeCategory.didChangeNotification เป็นสิ่งจำเป็นสำหรับแอพ UIKit

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม