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 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.
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.
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.
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.
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 — 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.
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 — 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.
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.
@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.
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:
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 Wrapper | Kepemilikan | Tipe | Kapan menggunakan |
|---|---|---|---|
| @State | Lokal | Value (struct, enum) | State sederhana satu View (penghitung, toggle, bidang teks) |
| @Binding | Eksternal | Referensi ke State | View anak yang mengubah data induk |
| @StateObject | Kepemilikan View | Reference (class) | Sumber kebenaran untuk model data kompleks |
| @ObservedObject | Injeksi | Reference (class) | Model dibuat di luar View (diteruskan melalui init) |
| @EnvironmentObject | Global | Reference (class) | Data yang dapat diakses seluruh hierarki (otentikasi, tema) |
Pertanyaan Umum
@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.
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.
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.
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.
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
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.
Baca juga