SwiftUI — konsep kunci, View, State dan Data Flow

Penulis: IT Sectr Diterbitkan: 2026-02-21 Waktu membaca: 8 mnt

SwiftUI — framework deklaratif Apple untuk membangun antarmuka pengguna di semua platform ekosistem, diperkenalkan di WWDC 2019. Berbeda dengan UIKit imperatif dengan viewDidLoad dan pembaruan layar manual, SwiftUI mendeskripsikan UI sebagai kumpulan struktur sederhana yang sesuai dengan protokol View. Menurut Swift.org (2025), SwiftUI digunakan dalam 65% proyek baru yang dipublikasikan di App Store. Framework secara otomatis mengelola pembaruan antarmuka melalui mekanisme State dan Data Flow — saat data berubah, View digambar ulang tanpa panggilan manual reloadData.

Poin Utama

  • SwiftUI — framework deklaratif Apple untuk UI (2019), di mana antarmuka dideskripsikan dengan struktur yang sesuai dengan protokol View.
  • View — blok bangunan dasar SwiftUI; setiap View mendeskripsikan bagian layarnya melalui computed property body.
  • @State — property wrapper untuk menyimpan state lokal, saat perubahannya View secara otomatis digambar ulang.
  • @Binding — koneksi dua arah antara View dan data, memungkinkan View anak mengubah state induk.
  • @ObservedObject dan @StateObject — koneksi dengan model data eksternal melalui kelas yang sesuai dengan protokol ObservableObject.

Apa itu SwiftUI?

SwiftUI — framework UI deklaratif Apple, yang secara radikal berbeda dari UIKit. Alih-alih membuat controller, view, dan mengelola siklus hidupnya secara manual, pengembang mendeskripsikan antarmuka dalam bentuk deklarasi: apa yang harus ada di layar, bukan bagaimana membangunnya. SwiftUI didasarkan pada prinsip reaktivitas: antarmuka adalah fungsi dari state. Saat state berubah, SwiftUI secara otomatis menghitung ulang body semua View yang bergantung dan hanya memperbarui bagian layar yang berubah. SwiftUI tersedia di iOS 13+, iPadOS 13+, macOS 10.15+, watchOS 6+, tvOS 13+ dan visionOS 1+. Kode SwiftUI bersifat lintas platform: satu file berfungsi di iPhone, iPad, Mac dan Apple Watch dengan adaptasi platform minimal. Menurut Apple WWDC Session 101 (2024), SwiftUI mencakup lebih dari 90% pola UI standar App Store.

SwiftUI vs UIKit

UIKit — framework imperatif (2008): pengembang membuat UIViewController, mengonfigurasi subviews di viewDidLoad, mengimplementasikan delegate/datasource untuk UITableView dan memperbarui layar melalui reloadData atau setNeedsLayout. SwiftUI menggantikan controller dengan struktur View sederhana, delegasi — dengan binding dan onChange, Auto Layout — dengan HStack/VStack/ZStack dan modifier (padding, frame, offset). UIKit memerlukan manajemen memori manual melalui ARC; SwiftUI — struktur yang tidak memerlukan penghitungan referensi. Performa SwiftUI sebanding dengan UIKit: framework menggunakan algoritma diffing untuk set perubahan minimal. Di IT Sectr, SwiftUI digunakan untuk proyek baru dengan target iOS 17+; proyek dengan dukungan iOS 14–15 memerlukan UIKit karena kompatibilitas SwiftUI yang terbatas.

Sintaks deklaratif SwiftUI

Di SwiftUI, antarmuka dideskripsikan melalui ViewBuilder — result builder yang mentransformasikan kumpulan View menjadi tuple atau Group. Modifier (.padding(), .font(), .foregroundColor()) membuat View baru dengan pengaturan yang dimodifikasi, tidak memutasi objek asli. Setiap modifier mengembalikan View baru, memungkinkan chaining. ViewBuilder mendukung if/else, switch, ForEach — rendering kondisional dan siklik tanpa controller terpisah. View di SwiftUI adalah value type (struct), yang menjamin perilaku yang dapat diprediksi dan menghilangkan race conditions.

Protokol View dan computed property body

View — protokol dengan satu persyaratan: computed property body bertipe some View. Setiap struktur yang sesuai dengan View mendeskripsikan bagian layarnya di body. Tipe some View — opaque return type yang menyembunyikan tipe konkret dari View yang dikembalikan (gabungan VStack, HStack, ZStack, Text, Image, dll.). Kompiler Swift menyimpulkan tipe konkret pada tahap kompilasi, mempertahankan performa panggilan langsung tanpa penghapusan tipe.

swift
import SwiftUI

struct GreetingView: View {
    var name: String
    
    var body: some View {
        VStack(spacing: 12) {
            Text("Halo, \(name)!")
                .font(.largeTitle)
                .foregroundColor(.primary)
            
            Text("Selamat datang di SwiftUI")
                .font(.body)
                .foregroundColor(.secondary)
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 12)
                .fill(.ultraThinMaterial)
        )
    }
}

Struktur GreetingView menerima parameter name dan menampilkan dua blok teks dalam tumpukan vertikal. Modifier .font, .foregroundColor, .padding dan .background mengonfigurasi tampilan. SwiftUI memanggil body setiap kali parameter input (name) berubah — penggambaran ulang hanya terjadi untuk bagian yang berubah. Dalam contoh, RoundedRectangle dengan .ultraThinMaterial digunakan — latar belakang blur native yang dibangun di SwiftUI.

@State: state lokal di SwiftUI

@State — property wrapper yang mendeklarasikan state lokal milik satu View. SwiftUI mengelola memori State secara otomatis: saat nilai berubah, body digambar ulang, tetapi hanya untuk View yang menggunakan State ini. State adalah sumber kebenaran (source of truth) untuk tipe sederhana (String, Int, Bool, enum). Jangan gunakan @State untuk model data kompleks — untuk itu tersedia @StateObject dan @ObservedObject. State harus private dan disimpan di View itu sendiri, tidak diteruskan antar komponen.

swift
import SwiftUI

struct CounterView: View {
    @State private var count = 0
    
    var body: some View {
        VStack(spacing: 20) {
            Text("Hitungan: \(count)")
                .font(.system(size: 48, weight: .bold))
            
            Button(action: { count += 1 }) {
                Label("Tambah", systemImage: "plus.circle")
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
    }
}

Nilai awal count = 0. Setiap penekanan tombol menaikkan count; SwiftUI secara otomatis menggambar ulang CounterView sepenuhnya (semua View). Di UIKit, skenario serupa akan memerlukan IBOutlet, IBAction dan pembaruan manual label.text. @State menjamin bahwa View hanya digambar ulang saat State tertentu berubah — algoritma diffing SwiftUI menemukan perubahan minimal di pohon.

@Binding: komunikasi dua arah antar View

@Binding — property wrapper yang membuat koneksi dua arah antara View dan data yang tidak dimiliki View. Binding adalah referensi ke State (atau sumber kebenaran lain), memungkinkan View anak membaca dan mengubah nilai yang disimpan di induk. Binding ditandai dengan prefiks $: $count meneruskan Binding<Int> ke View anak. Tanpa Binding, View anak tidak dapat mengubah data induk — hanya dapat membacanya.

swift
import SwiftUI

struct StepperControl: View {
    @Binding var value: Int
    let range: ClosedRange<Int>
    
    var body: some View {
        HStack {
            Button(action: { if value > range.lowerBound { value -= 1 } }) {
                Image(systemName: "minus.circle")
            }
            Text("\(value)")
                .frame(minWidth: 40)
            Button(action: { if value < range.upperBound { value += 1 } }) {
                Image(systemName: "plus.circle")
            }
        }
    }
}

struct ParentView: View {
    @State private var quantity = 5
    
    var body: some View {
        StepperControl(value: $quantity, range: 1...10)
    }
}

ParentView memiliki State quantity dan meneruskan Binding melalui $quantity. StepperControl dapat mengubah value, dan quantity di induk tersinkronisasi secara otomatis. Binding bukan salinan data, melainkan jembatan ke sumber kebenaran. Gunakan @Binding untuk kontrol kustom, editor, dan komponen yang dapat digunakan kembali yang harus mengubah data induk.

@ObservedObject dan @StateObject: model data eksternal

@StateObject — property wrapper untuk membuat dan memiliki instance kelas yang sesuai dengan ObservableObject. View membuat objek sekali per siklus hidup dan digambar ulang saat properti @Published-nya berubah. @ObservedObject — wrapper serupa, tetapi View tidak memiliki objek — objek dibuat dan disimpan di luar View (diteruskan melalui inisialisator). Apple merekomendasikan @StateObject untuk sumber kebenaran dalam hierarki View dan @ObservedObject untuk injeksi ketergantungan.

swift
import SwiftUI
import Combine

class UserSettings: ObservableObject {
    @Published var username: String = "Guest"
    @Published var isLoggedIn = false
}

struct ProfileView: View {
    @StateObject private var settings = UserSettings()
    
    var body: some View {
        VStack {
            TextField("Username", text: $settings.username)
                .textFieldStyle(.roundedBorder)
            
            Toggle("Logged In", isOn: $settings.isLoggedIn)
            
            if settings.isLoggedIn {
                Text("Selamat datang, \(settings.username)!")
                    .font(.headline)
            }
        }
        .padding()
    }
}

UserSettings — ObservableObject dengan dua properti @Published. ProfileView memiliki objek melalui @StateObject. Perubahan username atau isLoggedIn secara otomatis menggambar ulang ProfileView. @Published menggunakan Combine Publisher untuk memberi tahu SwiftUI tentang perubahan. Untuk meneruskan settings ke View anak, gunakan @ObservedObject:

Data Flow di SwiftUI: gambaran lengkap

Apple mendefinisikan empat tingkat Data Flow di SwiftUI: @State (lokal, value type), @Binding (dua arah), @StateObject/@ObservedObject (reference type dengan ObservableObject), @EnvironmentObject (global, injeksi melalui lingkungan). EnvironmentObject memungkinkan penerusan data melalui seluruh hierarki View tanpa penerusan eksplisit di inisialisator. Selain itu, @AppStorage bekerja dengan UserDefaults, @SceneStorage — dengan state scene, @FetchRequest — dengan Core Data. Pemilihan tingkat Data Flow menentukan arsitektur aplikasi: layar sederhana menggunakan State/Binding, modular — ObservedObject, berskala besar — EnvironmentObject + solusi mirip Redux (TCA, Composable Architecture).

Property WrapperKepemilikanTipeKapan menggunakan
@StateLokalValue (struct, enum)State sederhana satu View (penghitung, toggle, bidang teks)
@BindingEksternalReferensi ke StateView anak yang mengubah data induk
@StateObjectKepemilikan ViewReference (class)Sumber kebenaran untuk model data kompleks
@ObservedObjectInjeksiReference (class)Model dibuat di luar View (diteruskan melalui init)
@EnvironmentObjectGlobalReference (class)Data yang dapat diakses seluruh hierarki (otentikasi, tema)

Pertanyaan Umum

Apa perbedaan @State dengan @StateObject?

@State — untuk value types (struct, enum, String, Int) dan state lokal satu View. SwiftUI mengelola memori State secara otomatis. @StateObject — untuk reference types (class) yang sesuai dengan ObservableObject. @StateObject memiliki objek dan menggambar ulang View saat properti @Published berubah. Untuk penghitung sederhana gunakan @State; untuk model dengan logika — @StateObject.

Bisakah SwiftUI digunakan dengan UIKit?

Ya, SwiftUI terintegrasi dengan UIKit melalui UIHostingController (SwiftUI di dalam UIKit) dan UIViewRepresentable (UIKit di dalam SwiftUI). UIHostingController membungkus SwiftUI View ke dalam UIViewController. UIViewRepresentable memungkinkan penggunaan komponen UIKit (MKMapView, WKWebView) di SwiftUI. Ini adalah pendekatan standar untuk migrasi proyek dari UIKit ke SwiftUI.

Apa itu ViewBuilder di SwiftUI?

ViewBuilder — result builder (Swift 5.1) yang mentransformasikan kumpulan View menjadi satu nilai bertipe TupleView, Group atau ConditionalContent. ViewBuilder memungkinkan penulisan if/else dan switch imperatif di dalam body deklaratif. Tanpa ViewBuilder, harus mengembalikan AnyView atau Group untuk setiap blok kondisional. ViewBuilder adalah alasan mengapa dalam body tidak diperlukan koma antar View.

Apakah SwiftUI berfungsi di semua perangkat Apple?

Ya, SwiftUI mendukung iOS 13+, iPadOS 13+, macOS 10.15+, watchOS 6+, tvOS 13+ dan visionOS 1+. Namun beberapa API hanya tersedia di versi baru: misalnya, navigationStack (iOS 16+), Observable macro (iOS 17+). Untuk kompatibilitas mundur, gunakan #available dan adaptasi UIKit.

Bagaimana cara men-debug aplikasi SwiftUI?

Xcode Debug View Hierarchy menampilkan pohon SwiftUI View dengan modifier dan bingkai. Alat SwiftUI Inspector (panel kanan Xcode) memungkinkan pengubahan modifier secara real-time. self._printChanges() di body mencatat penyebab penggambaran ulang. Instruments dengan template SwiftUI melacak performa View dan mendeteksi penggambaran ulang berlebihan.

Kesimpulan

  • SwiftUI — framework deklaratif Apple untuk UI, di mana antarmuka dideskripsikan dengan struktur View dengan computed property body (2019).
  • View — value type (struct) yang sesuai dengan protokol View; body mengembalikan some View melalui ViewBuilder.
  • @State — state lokal untuk value types; saat berubah View secara otomatis digambar ulang.
  • @Binding — koneksi dua arah melalui prefiks $; View anak mengubah data induk.
  • @StateObject / @ObservedObject — reference types dengan ObservableObject dan properti @Published; StateObject memiliki objek, ObservedObject menerima dari luar.
  • @EnvironmentObject — state global untuk seluruh hierarki View; diinjeksi melalui .environmentObject().
  • Data Flow di SwiftUI — dari State (lokal) melalui Binding (dua arah) ke ObservedObject (modular) dan EnvironmentObject (global).

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga