SwiftUI: คืออะไร แนวคิดหลัก และ View Protocol

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

SwiftUI เป็นเฟรมเวิร์กแบบประกาศ (declarative) จาก Apple สำหรับสร้างส่วนติดต่อผู้ใช้บนทุกแพลตฟอร์มของระบบนิเวศ แทนที่จะอธิบายขั้นตอนแบบบังคับ (imperative) นักพัฒนาประกาศว่าส่วนติดต่อควรมีลักษณะอย่างไร และ SwiftUI จัดการการเรนเดอร์และอัปเดต ตาม Apple Developer Documentation (2025) SwiftUI รองรับ iOS 15+, iPadOS 15+, macOS 12+, watchOS 8+ และ tvOS 15+ และใช้ View Protocol เป็นส่วนประกอบพื้นฐานสำหรับคอมโพเนนต์อินเทอร์เฟซทั้งหมด

ประเด็นสำคัญ

  • SwiftUI เป็นเฟรมเวิร์กแบบประกาศของ Apple ที่นักพัฒนาอธิบายอินเทอร์เฟซและการอัปเดตจะดำเนินการโดยอัตโนมัติ
  • View Protocol พร้อมคุณสมบัติ body เป็นพื้นฐานของคอมโพเนนต์ UI SwiftUI ใด ๆ โดยคืนคำอธิบายหน้าจอผ่านการประกอบวิว (view composition)
  • Property Wrappers — @State, @Binding, @ObservedObject, @StateObject — จัดการสถานะและเริ่มต้นการวาดใหม่เมื่อข้อมูลเปลี่ยนแปลง
  • NavigationStack (iOS 16+) เป็น API การนำทางที่ทันสมัยพร้อมเส้นทางที่ปลอดภัยชนิด (type-safe routes) และการเปลี่ยนภาพแบบประกาศ
  • Modifier คือห่วงโซ่การเรียกเพื่อปรับแต่งลักษณะและพฤติกรรมของวิวโดยไม่ต้องสืบทอดคลาส

SwiftUI คืออะไร?

SwiftUI เป็นเฟรมเวิร์กแบบประกาศที่ Apple เปิดตัวในปี 2019 เพื่อแทนที่ UIKit ในโปรเจกต์ใหม่ แทนที่จะสร้างอินสแตนซ์ UIView ด้วยตนเองและเพิ่มลงในลำดับชั้น นักพัฒนาอธิบายอินเทอร์เฟซผ่านโครงสร้างที่สอดคล้องกับโปรโตคอล View SwiftUI จะคำนวณความแตกต่างระหว่างสถานะปัจจุบันและสถานะใหม่โดยอัตโนมัติและวาดเฉพาะส่วนที่เปลี่ยนแปลงโดยใช้เอนจินเรนเดอร์ของตัวเอง

เฟรมเวิร์กเขียนด้วย Swift โดยใช้ความหมายของค่า (value semantics) ซึ่งก็คือโครงสร้าง ไม่ใช่คลาส ทำให้คอมโพเนนต์ UI มีน้ำหนักเบาและปลอดภัยต่อเธรด แตกต่างจาก UIKit ที่ UIViewController อาจมีขนาด 200+ ไบต์เนื่องจาก Objective-C runtime ส่วน SwiftUI View เป็นเพียงโครงสร้างขนาดไม่กี่ไบต์ สิ่งนี้สำคัญโดยเฉพาะสำหรับ watchOS ที่มีหน่วยความจำจำกัด

SwiftUI ข้ามแพลตฟอร์ม

คำอธิบาย View เดียวกันทำงานบน iPhone, iPad, Mac, Apple Watch, Apple TV และ Apple Vision Pro SwiftUI ปรับอินเทอร์เฟซให้เข้ากับแพลตฟอร์ม: ท่าทางสัมผัสบน iOS, การกดแป้นพิมพ์บน macOS, การเลื่อน Digital Crown บน watchOS ซึ่งช่วยลดเวลาในการพัฒนาสำหรับบริษัทที่เผยแพร่แอปบนหลายแพลตฟอร์มของ Apple แต่ต้องมีการกำหนดค่าเพิ่มเติมสำหรับองค์ประกอบเฉพาะของแต่ละแพลตฟอร์ม

View Protocol และส่วนเนื้อหาของวิว

ใน SwiftUI แต่ละหน้าจอเป็นโครงสร้างที่ใช้โปรโตคอล View โดยมีข้อกำหนดเดียวคือคุณสมบัติที่คำนวณได้ body ชนิด some View คีย์เวิร์ด some (ชนิดโอเพค) ซ่อนชนิดรูปธรรมของวิว ทำให้ SwiftUI สามารถปรับการเรนเดอร์ให้เหมาะสม ภายใน body นักพัฒนาจะรวมคอมโพเนนต์สำเร็จรูป — Text, Image, Button, List — โดยใช้ ViewBuilder ซึ่งประกอบวิวหลายอันเป็นอันเดียว

swift
struct GreetingView: View {
    let name: String

    var var body: some View {
        VStack {
            Text("สวัสดี, \(name)!")
                .font(.title)
                .foregroundColor(.blue)
            Image(systemName: "hand.wave")
                .imageScale(.large)
        }
        .padding()
    }
}

ในตัวอย่าง VStack (สแต็กแนวตั้ง) ประกอบด้วย Text และ Image ค่าของ name ถูกส่งผ่านตัวเริ่มต้นโครงสร้าง — นี่คือวิธีที่ DI (การฉีดพึ่งพา) ทำงานใน SwiftUI โดยไม่ต้องใช้คอนเทนเนอร์ DI ภายนอก ตัวปรับแต่งแต่ละตัวจะคืนวิวใหม่ที่มีการเปลี่ยนแปลงที่ใช้ โดยไม่เปลี่ยนแปลงต้นฉบับ ซึ่งเป็นไปได้ด้วยความไม่เปลี่ยนเปลี่ยนของชนิดค่า (value types)

ViewBuilder และเงื่อนไข

ViewBuilder คือ result builder ที่มีคำอธิบาย @resultBuilder ซึ่งประกอบวิวได้สูงสุด 10 อันเป็นอันเดียว ภายใน body สามารถใช้ if/else, switch และ ForEach โดยไม่ต้องใช้ wrapper เพิ่มเติม ForEach ทำงานกับองค์ประกอบ Identifiable — วิวแต่ละอันจะได้รับ id เฉพาะสำหรับแอนิเมชันที่ถูกต้องเมื่อเพิ่ม/ลบ

การจัดการสถานะ: @State, @Binding, @ObservedObject

ใน SwiftUI สถานะเป็นตัวกำหนดว่าเนื้อหาใดจะแสดงบนหน้าจอ เมื่อสถานะเปลี่ยนแปลง SwiftUI จะสร้าง body ของวิวที่พึ่งพาใหม่และเปรียบเทียบผลลัพธ์กับก่อนหน้าโดยใช้อัลกอริทึม diff การจัดเก็บสถานะใช้ property wrappers — แต่ละตัวแก้ไขงานเฉพาะของมัน: สถานะภายในเครื่อง, การเชื่อมต่อกับวิวลูก, หรือโมเดลข้อมูลภายนอก

swift
struct CounterView: View {
    @State private var count = 0

    var var body: some View {
        VStack {
            Text("ตัวนับ: \(count)")
            Button("เพิ่ม") {
                count += 1
            }
        }
    }
}

class UserViewModel: ObservableObject {
    @Published var name = ""
    @Published var age = 0
}

@State จัดเก็บค่าท้องถิ่นอย่างง่าย (Int, String, Bool) ภายในโครงสร้าง View SwiftUI ย้ายหน่วยความจำจากโครงสร้างไปยังพื้นที่จัดเก็บแยกต่างหาก — ดังนั้นคุณสมบัติที่มี @State สามารถเปลี่ยนแปลงได้แม้ว่า View จะเป็นชนิดค่าก็ตาม @ObservableObject สำหรับคลาสที่มีคุณสมบัติ @Published ซึ่งการเปลี่ยนแปลงจะแจ้งให้ SwiftUI ทราบถึงความจำเป็นในการวาดใหม่โดยอัตโนมัติ

@Binding และการเชื่อมต่อพ่อแม่-ลูก

@Binding สร้างการเชื่อมต่อสองทิศทางกับแหล่งข้อมูลที่อยู่ในวิวแม่ แม่ส่ง $variable (ค่าที่ฉาย) และลูกอ่านและเขียนค่าผ่าน binding ซึ่งช่วยให้สามารถย้ายการป้อนข้อความหรือสวิตช์ไปยังคอมโพเนนต์แยกต่างหากในขณะที่เก็บสถานะไว้ในแม่ หากไม่มี @Binding การเปลี่ยนแปลงแต่ละครั้งจะต้องใช้คลอเซอร์ callback เพื่อส่งค่าใหม่ขึ้นไปข้างบน

ก่อน iOS 16 การนำทางใน SwiftUI สร้างขึ้นบน NavigationView — API ดั้งเดิมที่มีพฤติกรรมซับซ้อนบน iPad (มุมมองแยก, สองคอลัมน์) เริ่มตั้งแต่ iOS 16 Apple แนะนำ NavigationStack — ทางเลือกที่เรียบง่ายพร้อมเส้นทางที่ปลอดภัยชนิด นักพัฒนากำหนด enum ของเส้นทางที่เป็นไปได้ และ NavigationStack จัดการสแต็กหน้าจอโดยอัตโนมัติพร้อมรองรับ deep link และกลับไปยังราก

swift
enum Route: Hashable {
    case detail(id: Int)
    case settings
}

struct ContentView: View {
    var var body: some View {
        NavigationStack {
            List {
                NavigationLink("หน้าจอรายละเอียด",
                               value: Route.detail(id: 42))
                NavigationLink("การตั้งค่า",
                               value: Route.settings)
            }
            .navigationDestination(for: Route.self) { route in
                switch route {
                case .detail(let id): DetailView(id: id)
                case .settings: SettingsView()
                }
            }
        }
    }
}

เส้นทางที่สอดคล้องกับ Hashable อนุญาตให้ใช้ชนิดข้อมูลใด ๆ ในการส่งพารามิเตอร์ navigationDestination(for:destination:) เชื่อมโยงชนิดเส้นทางกับวิวเป้าหมาย ข้อได้เปรียบเหนือการนำทาง UIKit คือไม่ต้องวาดใหม่เมื่อเพิ่มเส้นทางใหม่: เพียงเพิ่ม case ใน enum และ handler ใน switch Deep link จะถูกจัดการผ่าน processDeepLink บน NavigationStack

การนำทางแบบโปรแกรม

สำหรับการนำทางแบบโปรแกรม (หลังจากเข้าสู่ระบบ, ตัวจับเวลา หรือการตอบสนองของเซิร์ฟเวอร์) ใช้ @State กับตัวเริ่มต้น NavigationLink: NavigationLink(isActive: $isActive) เมื่อ isActive = true การเปลี่ยนภาพจะเกิดขึ้นโดยไม่ต้องสัมผัสผู้ใช้ ทางเลือกอื่นคือการ bind อาร์เรย์ $path ใน NavigationStack: $path.append(Route.detail(id: 1))

View Modifier — การปรับแต่งลักษณะ

Modifier เป็นเมธอดที่คืนสำเนาที่ถูกปรับเปลี่ยนของวิว แตกต่างจาก UIKit ที่การกำหนดค่าคุณสมบัติทำได้โดยการเปลี่ยนวิวที่มีอยู่ SwiftUI สร้างค่าใหม่ด้วยการเปลี่ยนแปลงที่ใช้ การต่อสายตัวปรับแต่งสร้างอินเทอร์เฟซสุดท้ายจากการแปลงตามลำดับ: แบบอักษร → ระยะห่าง → สี → เงา → ท่าทาง

Apple มีตัวปรับแต่งในตัวมากกว่า 200 ตัว ที่พบบ่อยที่สุด: .font(), .foregroundColor(), .padding(), .background(), .cornerRadius(), .shadow(), .opacity(), .offset() ลำดับของตัวปรับแต่งสำคัญ: .padding() ก่อน .background() จะเติมพื้นที่ด้วยระยะห่าง หลังจากนั้น — เฉพาะพื้นที่ด้านใน ตัวปรับแต่งแบบกำหนดเอง สร้างขึ้นผ่านโปรโตคอล ViewModifier

ตัวปรับแต่งแบบมีเงื่อนไขและแอนิเมชัน

ตัวปรับแต่งสามารถใช้แบบมีเงื่อนไขผ่านตัวดำเนินการ ternary: .foregroundColor(isError ? .red : .primary) สำหรับแอนิเมชันใช้ .animation(.easeInOut, value: state) — ตัวปรับแต่งแอนิเมชันจะผูกกับคุณสมบัติสถานะเฉพาะ เมื่อคุณสมบัตินี้เปลี่ยนแปลง SwiftUI จะเคลื่อนไหวการเปลี่ยนระหว่างค่าเก่าและค่าใหม่ แอนิเมชัน ทำงานกับ opacity, offset, scale, rotation, ขนาดและสี — แต่ละคุณสมบัติมี AnimatableParameter ที่สอดคล้องกัน

สำหรับแอนิเมชันแบบกำหนดเอง มี .transition (ปรากฏ/หายไป) และ .matchedGeometryEffect (การเปลี่ยนองค์ประกอบอย่างราบรื่นระหว่างสองคอนเทนเนอร์) อย่างหลังใช้สำหรับแอนิเมชัน hero ในรายการ: ไอคอนในเซลล์รายการค่อย ๆ เปลี่ยนเป็นภาพขนาดใหญ่บนหน้าจอรายละเอียด

SwiftUI vs UIKit: การเปรียบเทียบแนวทาง

การเลือกระหว่าง SwiftUI และ UIKit เป็นหนึ่งในปัญหาที่นักพัฒนา iOS ต้องเผชิญเป็นอันดับแรก ทั้งสองเฟรมเวิร์กรองรับโดย Apple แต่แก้ปัญหาการสร้างอินเทอร์เฟซด้วยวิธีที่แตกต่างกันโดยพื้นฐาน: SwiftUI แบบประกาศ, UIKit แบบบังคับ ความแตกต่างปรากฏในการจัดการสถานะ การนำทาง ประสิทธิภาพและความเข้ากันได้

ด้านSwiftUIUIKit
แนวทางประกาศ: แสดงอะไรบังคับ: วิธีสร้าง
สถานะProperty Wrappers, การวาดใหม่อัตโนมัติด้วยตนเอง: reloadData, setNeedsLayout
โค้ด UIกระชับ, สายตัวปรับแต่งเยิ่นเย้อ, NSCoder/Storyboard/ข้อจำกัด
ประสิทธิภาพสูงบน iOS 17+, อัลกอริทึม diffสูงสุดบน iOS 12–16, ควบคุมโดยตรง
รุ่นต่ำสุดiOS 15+ (รองรับเต็มที่)iOS 2+ (ทุกรุ่น)

สำหรับโปรเจกต์ใหม่ที่มีรุ่น iOS 17 ขั้นต่ำ Apple แนะนำ SwiftUI เป็นเฟรมเวิร์กหลัก UIKit ยังคงจำเป็นสำหรับอินเทอร์เฟซที่ต้องการการควบคุมการเรนเดอร์อย่างละเอียด (UICollectionViewLayout แบบกำหนดเอง, ฉาก CAAnimation ที่ซับซ้อน) หรือรองรับ iOS 12–14 หลายโปรเจกต์ใช้แนวทางแบบผสมผสาน: SwiftUI ผ่าน UIHostingController ถูกฝังในแอป UIKit และ UIViewRepresentable อนุญาตให้ใช้คอมโพเนนต์ UIKit ภายในลำดับชั้น SwiftUI

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

สามารถใช้ SwiftUI และ UIKit ในโปรเจกต์เดียวกันได้หรือไม่?

ได้ ผ่าน UIHostingController (SwiftUI ใน UIKit) และ UIViewRepresentable (UIKit ใน SwiftUI) เป็นแนวทางแบบผสมผสานที่นิยมระหว่างการย้ายข้อมูล

ควรเริ่มโปรเจกต์ SwiftUI ด้วย iOS รุ่นใด?

iOS 17 ให้ฟังก์ชันการทำงานเต็มรูปแบบ: NavigationStack, Observation framework, Swift Charts iOS 15 เป็นเกณฑ์ขั้นต่ำสำหรับการผลิต

ทำไม SwiftUI บางครั้งไม่อัปเดตอินเทอร์เฟซ?

สาเหตุที่พบบ่อยที่สุดคือการเปลี่ยนคุณสมบัติ @Published บนเธรดพื้นหลัง ObservableObject ต้องส่งการเปลี่ยนแปลงบน main actor: @MainActor class ViewModel

วิธีจัดการ debounce เมื่อกดปุ่มใน SwiftUI?

ใช้ .debounce ผ่าน Combine: Button.publisher(for: .tap) .debounce(for: .seconds(0.3), scheduler: RunLoop.main)

SwiftUI รองรับท่าทางแบบกำหนดเองหรือไม่?

ใช่ ผ่านตัวปรับแต่ง Gesture: DragGesture, LongPressGesture, MagnificationGesture, RotationGesture รวมกันโดยใช้ .simultaneousGesture() และ .sequenced()

สรุป

  • SwiftUI เป็นเฟรมเวิร์กแบบประกาศของ Apple ที่อินเทอร์เฟซถูกอธิบายเป็นองค์ประกอบของโครงสร้าง View พร้อม property wrappers สำหรับจัดการสถานะ
  • View Protocol พร้อมคุณสมบัติที่คำนวณได้ body เป็นจุดเข้าเดียวสำหรับวิวใด ๆ ViewBuilder ประกอบวิวได้สูงสุด 10 อันเป็นอันเดียวโดยไม่ต้องใช้คอนเทนเนอร์เพิ่มเติม
  • @State, @Binding และ @ObservedObject ครอบคลุมทุกสถานการณ์การจัดการข้อมูล: สถานะภายในเครื่อง การเชื่อมต่อพ่อแม่ลูกและโมเดลภายนอก
  • NavigationStack พร้อมเส้นทาง enum ที่ปลอดภัยชนิดแทนที่ NavigationView เพิ่มการรองรับ deep link และการนำทางแบบโปรแกรม
  • Modifier เป็นแพทเทิร์นหลักของ SwiftUI ที่ช่วยให้ปรับแต่งลักษณะของวิวผ่านห่วงโซ่การเรียกโดยไม่ต้องสืบทอด
  • SwiftUI และ UIKit อยู่ร่วมกันผ่าน UIHostingController และ UIViewRepresentable ทำให้สามารถย้ายโปรเจกต์ทีละน้อย
  • สำหรับ iOS 17+ Apple แนะนำ SwiftUI เป็นเฟรมเวิร์กหลัก UIKit ยังคงอยู่สำหรับอินเทอร์เฟซแบบกำหนดเองที่ซับซ้อนและการรองรับรุ่นเก่า

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

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

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

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