SwiftUI ในการพัฒนามือถือ: คืออะไร แนวคิดหลัก และวิธีการทำงาน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-02 เวลาอ่าน: 10 นาที
SwiftUI คือเฟรมเวิร์กแบบประกาศของ Apple สำหรับสร้างอินเทอร์เฟซบนทุกแพลตฟอร์ม ตาม Apple SwiftUI Docs (2025) พบว่า SwiftUI ถูกใช้ใน 70% ของแอปใหม่บน App Store การทำความเข้าใจแนวคิดหลักของ SwiftUI — View Protocol, @ViewBuilder, NavigationStack — เป็นพื้นฐานของการพัฒนา iOS สมัยใหม่

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

  • View Protocol — var body: some View แต่ละ View คือโครงสร้างที่สอดคล้องกับโปรโตคอล View body คือคำอธิบาย UI
  • @ViewBuilder — Result Builder สำหรับหลาย Views ในคอนเทนเนอร์ if/else, switch, ForEach ภายใน body
  • NavigationStack (iOS 16+) — การนำทางที่ขับเคลื่อนด้วยข้อมูล แบบ path-based, deep linking แทนที่ NavigationView
  • @StateObject — การเป็นเจ้าของออบเจกต์ @ObservedObject — การสังเกต @EnvironmentObject — สภาพแวดล้อม
  • @FocusState — การจัดการโฟกัส .task{}, .onAppear{} — วงจรชีวิต PreviewProvider — ตัวอย่าง

พื้นฐาน (View Protocol, body, some View, @ViewBuilder)

View Protocol คือโปรโตคอลหลักของ SwiftUI ต้องการคุณสมบัติเดียว: var body: some View body คือคุณสมบัติที่คำนวณแล้วซึ่งส่งคืนคำอธิบาย UI SwiftUI จะเรียก body ทุกครั้งที่สถานะเปลี่ยนแปลงและเรนเดอร์ผลลัพธ์บน GPU

@ViewBuilder

@ViewBuilder คือ Result Builder สำหรับ View อนุญาตให้เขียนหลาย Views ภายใน closure โดยไม่ต้อง return และไม่มี TupleView รองรับ if/else, switch, ForEach คอนเทนเนอร์ทั้งหมด (VStack, HStack, ZStack, Group) ใช้ @ViewBuilder ทางเลือกอื่นคือ Group { … } สำหรับการจัดกลุ่มโดยไม่ต้องมีเลย์เอาต์ some View คือ Opaque Type คอมไพเลอร์รู้ประเภท View ที่เป็นรูปธรรม (Text, Button, VStack ฯลฯ) แต่ส่งคืนภายนอกเป็น some View ซึ่งช่วยให้เปลี่ยนประเภท body โดยไม่เปลี่ยนลายเซ็น ViewModifier — ตัวดัดแปลง View: .font(), .padding(), .background() ตัวดัดแปลงที่กำหนดเองผ่าน ViewModifier protocol และ .modifier()

swift
// ตัวอย่าง View ด้วย @ViewBuilder และ NavigationStack
struct ContentView: View {
    @State private var items = ["Item 1", "Item 2"]

    var body: some View {
        NavigationStack {
            List(items, id: .self) { item in
                NavigationLink(item) {
                    DetailView(item: item)
                }
            }
            .navigationTitle("Items")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Add") {
                        items.append("New Item")
                    }
                }
            }
        }
    }
}

// DetailView ด้วย @StateObject
struct DetailView: View {
    let item: String
    @StateObject private var viewModel = DetailViewModel()

    var body: some View {
        Text(item)
            .task {
                await viewModel.loadDetails(for: item)
            }
    }
}

ตัวดัดแปลงและคอนเทนเนอร์ (ViewModifier, NavigationStack, List, Form)

NavigationStack (iOS 16+) — การนำทางที่ขับเคลื่อนด้วยข้อมูล รับเส้นทาง (อาร์เรย์ของค่าที่แฮชได้) และแสดงปลายทางผ่าน navigationDestination แทนที่ NavigationLink ด้วยวิวปลายทาง NavigationLink — ปุ่มสำหรับนำทางในสแต็ก List — รายการแนวตั้งพร้อมส่วนต่างๆ การปัด การลบ และการลากและวาง Form — List เฉพาะสำหรับการตั้งค่า: ส่วนต่างๆ ตัวเลือก สวิตช์ ฟิลด์ข้อความ Section — การจัดกลุ่มใน List/Form พร้อมส่วนหัวและส่วนท้าย ViewModifier — ตัวดัดแปลงที่กำหนดเองสำหรับการใช้สไตล์ซ้ำ .modifier(CustomModifier()) — การใช้งาน

List และ Form โดยละเอียด

List ใน SwiftUI เทียบเท่ากับ UITableView รองรับ .onDelete, .onMove, .refreshable SwipeActions — .swipeActions { Button("ลบ", role: .destructive) { } } Form — เพิ่มประสิทธิภาพสำหรับการตั้งค่า: DatePicker, Toggle, Stepper, Picker Section พร้อม header/footer — สำหรับการจัดกลุ่ม OutlineGroup — รายการแบบลำดับชั้น (เทียบเท่า UITableView พร้อมส่วนต่างๆ) DisclosureGroup — ส่วนที่ยุบได้พร้อมเนื้อหา IT Sectr แนะนำ List สำหรับข้อมูลและ Form สำหรับการตั้งค่า

PreviewProvider — โปรโตคอลสำหรับตัวอย่างใน Xcode Canvas Canvas — ตัวอย่าง SwiftUI แบบโต้ตอบ (ต้องการ @main และ Swift 5.9+) @ScaledMetric — ขนาดที่ปรับเปลี่ยนได้ซึ่งปรับขนาดตาม Dynamic Type

การจัดการสถานะ (@StateObject, @ObservedObject, @EnvironmentObject, @FocusState)

Property Wrappers คือพื้นฐานของการจัดการสถานะใน SwiftUI @State — สถานะท้องถิ่น (value type) @Binding — การเชื่อมต่อกับสถานะแม่ @StateObject — สร้าง ObservableObject SwiftUI จัดการวงจรชีวิตของออบเจกต์ @ObservedObject — สังเกต ObservableObject ภายนอก @EnvironmentObject — ออบเจกต์จากสภาพแวดล้อม (การฉีดการพึ่งพาผ่าน .environmentObject()) @Environment — ค่าระบบ (.colorScheme, .locale) @AppStorage — UserDefaults @FetchRequest — คำสั่ง Core Data @FocusState — โฟกัสอินพุต

ตัวห่อ วัตถุประสงค์ ความเป็นเจ้าของ
@Stateสถานะท้องถิ่น (value type)View เป็นเจ้าของ
@Bindingการเชื่อมต่อกับสถานะแม่แม่เป็นเจ้าของ
@StateObjectสร้าง ObservableObjectView เป็นเจ้าของ
@ObservedObjectสังเกตออบเจกต์ภายนอกเจ้าของภายนอก
@EnvironmentObjectออบเจกต์จากสภาพแวดล้อมบรรพบุรุษเป็นเจ้าของ
@Environmentค่าระบบระบบ
@AppStorageUserDefaultsUserDefaults
@FocusStateโฟกัสอินพุตView เป็นเจ้าของ

@StateObject vs @ObservedObject: @StateObject สร้างออบเจกต์ @ObservedObject สังเกตมัน ใช้ @StateObject สำหรับการสร้างโมเดลครั้งแรกในลำดับชั้น @ObservedObject สำหรับส่งต่อให้วิวลูก @FocusState — การจัดการโฟกัส: .focused($field, equals: .email) รองรับ enum สำหรับหลายฟิลด์

ค่สภาพแวดล้อมและ DI

@Environment — ค่าระบบ: colorScheme, locale, sizeCategory, layoutDirection, managedObjectContext ค่สภาพแวดล้อมที่กำหนดเอง — ค่าที่กำหนดเองผ่าน EnvironmentKey ใช้สำหรับการฉีดการพึ่งพา: ส่งบริการโดยไม่มีพารามิเตอร์ที่ชัดเจน ตัวดัดแปลง .environment() — ตั้งค่าในลำดับชั้น @EnvironmentObject — ObservableObject จาก .environmentObject() แตกต่างจาก @Environment ตรงที่ส่งประเภทอ้างอิง IT Sectr แนะนำ @Environment สำหรับค่าระบบและ @EnvironmentObject สำหรับบริการ

วงจรชีวิต (.task, .onAppear, .onDisappear)

.task{} — การดำเนินการแบบอะซิงโครนัสเมื่อวิวปรากฏ การยกเลิกอัตโนมัติเมื่อหายไป แทนที่ .onAppear สำหรับ async/await .onAppear{} — การดำเนินการแบบซิงโครนัสเมื่อปรากฏ .onDisappear{} — การดำเนินการเมื่อหายไป .onChange(of:) — การตอบสนองต่อการเปลี่ยนแปลงค่า .onReceive(Publisher) — การตอบสนองต่อผู้เผยแพร่ Combine วงจรชีวิตของ View ใน SwiftUI: init → onAppear → body (การเรนเดอร์) → onDisappear เมื่อสถานะเปลี่ยน: body → diff → การเรนเดอร์ใหม่ IT Sectr แนะนำ .task สำหรับการโหลดแบบอะซิงโครนัสและ .onAppear สำหรับการวิเคราะห์

แอนิเมชันใน SwiftUI

.animation() — ตัวดัดแปลงแอนิเมชัน .transition() — แอนิเมชันปรากฏ/หายไป withAnimation — แอนิเมชันการเปลี่ยนสถานะอย่างชัดแจ้ง matchedGeometryEffect — แอนิเมชันระหว่างวิวต่างๆ (hero animation) PhaseAnimator (iOS 17+) — แอนิเมชันหลายเฟสตาม enum KeyframeAnimator (iOS 17+) — แอนิเมชันทีละเฟรมด้วยคีย์เฟรม แอนิเมชัน SwiftUI ทำงานบน GPU ผ่าน Core Animation IT Sectr แนะนำ .spring() สำหรับแอนิเมชันที่เป็นธรรมชาติและ .interpolatingSpring สำหรับเอฟเฟกต์ทางกายภาพ

การไหลของข้อมูล (Bindings, @Published, ObservableObject)

ObservableObject — โปรโตคอลสำหรับออบเจกต์ที่มีคุณสมบัติ @Published SwiftUI สมัครรับข้อมูลจากผู้เผยแพร่ objectWillChange @Published — เผยแพร่การเปลี่ยนแปลงคุณสมบัติ @StateObject — สร้าง ObservableObject จัดการวงจรชีวิต @ObservedObject — สังเกตภายนอก Combine — เฟรมเวิร์กสำหรับการเขียนโปรแกรมเชิงรับ @EnvironmentObject — DI ผ่านสภาพแวดล้อม .environmentObject() ตั้งค่า @EnvironmentObject อ่าน MVVM — สถาปัตยกรรมมาตรฐาน: View (SwiftUI) — ViewModel (ObservableObject) — Model IT Sectr แนะนำ MVVM + @StateObject สำหรับ ViewModel หลัก

swift
class UserViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var isLoading = false

    func loadUsers() async {
        isLoading = true
        defer { isLoading = false }
        do {
            users = try await api.fetchUsers()
        } catch {
            print("ข้อผิดพลาด: \(error)")
        }
    }
}

struct UsersView: View {
    @StateObject private var viewModel = UserViewModel()

    var body: some View {
        List(viewModel.users, id: \.id) { user in
            Text(user.name)
        }
        .task { await viewModel.loadUsers() }
        .overlay {
            if viewModel.isLoading { ProgressView() }
        }
    }
}

การเข้าถึงและการแปลภาษา

การเข้าถึง ใน SwiftUI: .accessibilityLabel(), .accessibilityHint(), .accessibilityValue(), .accessibilityAddTraits() VoiceOver อ่านป้ายกำกับการเข้าถึง Dynamic Type — @ScaledMetric, @DynamicProperty การแปลภาษา: String(localized:) (SwiftUI + String Catalog) LocalizedStringKey — การแปลอัตโนมัติ กฎพหูพจน์ — ผ่าน String Catalog (one, few, many, other) จากขวาไปซ้าย (อาหรับ, ฮีบรู) — รองรับโดยอัตโนมัติ .environment(.layoutDirection, .rightToLeft) IT Sectr แนะนำป้ายกำกับการเข้าถึงสำหรับองค์ประกอบเชิงโต้ตอบทั้งหมด

swift
struct AccessibleButton: View {
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            Label("Settings", systemImage: "gear")
        }
        .accessibilityLabel("Open Settings")
        .accessibilityHint("Double tap to navigate to settings screen")
        .accessibilityAddTraits(.isButton)
    }
}

// การรองรับ Dynamic Type
struct ScalableText: View {
    @ScaledMetric private var fontSize: CGFloat = 17

    var body: some View {
        Text("Hello, World!")
            .font(.system(size: fontSize))
    }
}

แผนภูมิและการแสดงภาพ (Swift Charts)

Swift Charts (iOS 16+) — เฟรมเวิร์กสำหรับสร้างแผนภูมิ Chart { } — คอนเทนเนอร์พื้นฐาน BarMark, LineMark, PointMark, AreaMark, RuleMark — เครื่องหมาย ForEach สำหรับข้อมูล ChartAxis — การปรับแต่งแกน .chartXAxis, .chartYAxis ChartLegend — คำอธิบาย การประมาณค่า — catmullRom, linear, step แอนิเมชัน — .animation() สำหรับ Chart IT Sectr แนะนำ Swift Charts สำหรับแผนภูมิในตัวและ Charts (DGCharts) สำหรับแผนภูมิที่ซับซ้อน

swift
import Charts

struct MonthlySales: Identifiable {
    let id = UUID()
    let month: String
    let sales: Double
}

struct SalesChart: View {
    let data: [MonthlySales]

    var body: some View {
        Chart(data) { item in
            BarMark(
                x: .value("Month", item.month),
                y: .value("Sales", item.sales)
            )
            .foregroundStyle(.blue.gradient)
        }
        .chartXAxisLabel("Month")
        .chartYAxisLabel("Sales")
        .frame(height: 200)
        .padding()
    }
}

Swift Package Manager (SPM) — ตัวจัดการการพึ่งพาของ Apple รวมอยู่ใน Xcode รองรับ: แพ็กเกจไบนารี ทรัพยากร การทดสอบ swift-6 การทำงานพร้อมกันอย่างเคร่งครัด การเผยแพร่แพ็กเกจผ่าน GitHub ด้วยแท็ก semver SPM เป็นมาตรฐานโดยพฤตินัยสำหรับการพึ่งพา Swift แทนที่ CocoaPods และ Carthage IT Sectr แนะนำ SPM สำหรับโปรเจกต์ใหม่ทั้งหมด

Swift Concurrency (async/await, TaskGroup, AsyncSequence) — async/await สร้างใน Swift 5.5+ Task — หน่วยของอะซิงโครนี TaskGroup — งานแบบขนาน AsyncSequence — ลำดับแบบอะซิงโครนัส (AsyncStream, AsyncAlgorithms) Task Local Values — ข้อมูลบริบทสำหรับ Task Swift Concurrency แทนที่ Combine อย่างสมบูรณ์สำหรับการดำเนินการแบบอะซิงโครนัส

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

View Protocol ใน SwiftUI คืออะไร?

View Protocol คือโปรโตคอลพื้นฐาน ต้องการ var body: some View body คือคำอธิบาย UI ที่เรนเดอร์บน GPU

@ViewBuilder คืออะไรและจำเป็นเพราะอะไร?

@ViewBuilder คือ Result Builder สำหรับหลาย Views อนุญาต if/else, switch, ForEach ภายในคอนเทนเนอร์

ความแตกต่างระหว่าง @StateObject และ @ObservedObject คืออะไร?

@StateObject สร้างออบเจกต์ @ObservedObject สังเกตออบเจกต์ที่มีอยู่ @StateObject สำหรับการสร้างครั้งแรกในลำดับชั้น

NavigationStack ใน iOS 16+ คืออะไร?

NavigationStack — การนำทางที่ขับเคลื่อนด้วยข้อมูล แบบ path-based, deep linking แทนที่ NavigationView

@FocusState ทำงานอย่างไรใน SwiftUI?

@FocusState — การจัดการโฟกัสอินพุต ตัวดัดแปลง .focused() รองรับ enum สำหรับหลายฟิลด์

สรุป

  • View Protocol — var body: some View พื้นฐานของ SwiftUI แต่ละ View คือ struct
  • @ViewBuilder — ไวยากรณ์แบบประกาศสำหรับหลาย Views if/else, ForEach ภายใน body
  • NavigationStack (iOS 16+) — การนำทางที่ทันสมัย data-driven, path-based
  • @StateObject — ความเป็นเจ้าของโมเดล @ObservedObject — การสังเกต @EnvironmentObject — DI
  • @FocusState — การจัดการโฟกัส มีประโยชน์สำหรับฟอร์มและฟิลด์อินพุตหลายฟิลด์
  • .task{} — การดำเนินการแบบอะซิงโครนัสพร้อมการยกเลิกอัตโนมัติ .onAppear{} — แบบซิงโครนัส
  • PreviewProvider และ Canvas — ตัวอย่างใน Xcode @ScaledMetric — ขนาดที่ปรับเปลี่ยนได้

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

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

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