Belajar Swift - SwiftUI & Declarative UI
Episode 17 of 23

Belajar Swift - SwiftUI & Declarative UI

Episode ini membahas SwiftUI: dasar views dan layout secara deklaratif, state management dengan @State, @Binding, @ObservedObject, dan @EnvironmentObject, animasi serta transisi untuk UI yang adaptif, dan interoperabilitas antara UIKit dan SwiftUI.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

SwiftUI mengubah cara kalian membangun antarmuka: dari imperatif ("lakukan ini, lalu itu") menjadi deklaratif ("begini yang kalian inginkan"). Episode 17 membahas SwiftUI dan declarative UI — mulai dari konsep dasar views dan layout, state management dengan property wrappers, hingga animasi dan interoperabilitas dengan UIKit.

Dengan SwiftUI, kalian mendeskripsikan UI sebagai fungsi dari state: saat state berubah, SwiftUI menghitung ulang tampilan dan memperbarui apa yang berubah. Memahami model state ini adalah kunci menguasai SwiftUI.

Dasar Views dan Layout

Mendeskripsikan UI Secara Deklaratif

View di SwiftUI adalah struct yang mendeskripsikan tampilan dan perilakunya:

View pertama di SwiftUI
import SwiftUI
 
struct GreetingView: View {
    var body: some View {
        VStack(spacing: 12) {
            Text("Halo, SwiftUI")
                .font(.largeTitle)
            Text("Belajar deklaratif")
        }
        .padding()
    }
}

struct GreetingView: View menyatakan bahwa view adalah data — kombinasi komponen dengan modifier seperti .font dan .padding. VStack menyusun anaknya secara vertikal. UI ini akan tampil sama di iPhone, iPad, Mac, Apple Watch, dan Apple TV.

Layout dengan Stack

Komposisi layout dibangun dari tiga stack dasar:

  • HStack: menyusun anak secara horizontal.
  • VStack: menyusun anak secara vertikal.
  • ZStack: menumpuk anak pada sumbu kedalaman.
Kombinasi stack
HStack {
    Image(systemName: "heart.fill")
    Text("Menyukai Swift")
}
.padding(12)

HStack { ... } menempatkan icon dan teks sejajar. Stack dikombinasikan bebas membentuk layout yang kompleks, dengan Spacer dan frame untuk mengatur distribusi ruang.

State Management

@State dan @Binding

@State adalah sumber kebenaran lokal view. Saat nilai berubah, view di-render ulang:

@State dan @Binding
struct CounterView: View {
    @State private var jumlah = 0
 
    var body: some View {
        VStack {
            Text("Jumlah: \(jumlah)")
            TombolTambah(jumlah: $jumlah)
        }
    }
}
struct TombolTambah: View {
    @Binding var jumlah: Int
 
    var body: some View {
        Button("Tambah") {
            jumlah += 1
        }
    }
}

@State private var jumlah = 0 menyimpan state lokal view, dan @Binding var jumlah: Int membiarkan view anak membaca serta mengubah state milik view induk. Binding menjaga satu sumber kebenaran tanpa memindahkan state ke anak.

@ObservedObject dan @EnvironmentObject

Untuk state yang dibagikan lebih luas, episode 16 memperkenalkan @StateObject. Ketika object state dimiliki di tempat lain, gunakan @ObservedObject; dan untuk menyuntikkan ke seluruh hierarki, gunakan @EnvironmentObject:

EnvironmentObject di hierarki
@main
struct AppUtama: App {
    @StateObject var sesi = SesiPengguna()
 
    var body: some Scene {
        WindowGroup {
            KontenView()
                .environmentObject(sesi)
        }
    }
}

.environmentObject(sesi) membuat sesi tersedia bagi setiap view di bawahnya tanpa meneruskannya satu per satu. View yang membutuhkannya cukup mendeklarasikan @EnvironmentObject var sesi: SesiPengguna. Ini cara paling praktis untuk state global seperti sesi login dan tema.

Animasi dan Transisi

Animasi Implisit dan Eksplisit

SwiftUI menganimasikan perubahan state secara otomatis dengan .animation (implisit) atau withAnimation (eksplisit):

Animasi dengan withAnimation
struct AnimasiView: View {
    @State private var diperbesar = false
 
    var body: some View {
        Button("Tekan") {
            withAnimation(.spring(response: 0.4, dampingFraction: 0.6)) {
                diperbesar.toggle()
            }
        }
        .scaleEffect(diperbesar ? 1.4 : 1.0)
    }
}

withAnimation(.spring(...)) { diperbesar.toggle() } menganimasikan perubahan yang terjadi di dalam bloknya — di sini, perubahan scale pada tombol. Pilih durasi dan kurva yang sesuai; spring memberi efek alami untuk interaksi pengguna.

Transisi Antar View

Perubahan tampilan antar state juga bisa dianimasikan dengan transisi:

Transisi dengan transition
if ditampilkan {
    DetailView()
        .transition(.opacity.combined(with: .slide))
}

.transition(.opacity.combined(with: .slide)) menggabungkan efek memudar dan geser saat view muncul atau menghilang. Transisi membutuhkan animasi di sekitarnya — tanpa withAnimation atau .animation, perubahan terjadi seketika.

Adaptive UI dan Interop UIKit

UI Adaptif

SwiftUI menyesuaikan diri dengan ukuran layar lewat kemampuan responsif: HStack bisa beralih ke VStack bergantung pada horizontal size class. Gunakan @Environment untuk membaca ukuran, dan ViewThatFits untuk memilih layout yang cocok dengan ruang yang tersedia.

Interop UIKit dan SwiftUI

SwiftUI dan UIKit hidup berdampingan dalam satu project. UIViewRepresentable membungkus UIKit view agar bisa dipakai SwiftUI, dan UIViewControllerRepresentable membungkus View Controller:

Membungkus UIKit di SwiftUI
import UIKit
import SwiftUI
 
struct MapViewWrapper: UIViewRepresentable {
    func makeUIView(context: Context) -> MKMapView {
        return MKMapView()
    }
 
    func updateUIView(_ uiView: MKMapView, context: Context) {}
}

makeUIView(context:) membuat view UIKit dan updateUIView(_:context:) memperbaruinya saat SwiftUI berubah. Interop ini berarti kalian bisa mengadopsi SwiftUI bertahap tanpa membuang UIKit lama — arah sebaliknya, menyematkan SwiftUI di UIKit, memakai UIHostingController.

Info

Property wrapper adalah inti model state SwiftUI. Mulailah dengan @State untuk state lokal, @Binding untuk meneruskan, lalu @StateObject dan @EnvironmentObject untuk state yang dibagikan. Urutan ini menjaga arsitektur kalian tetap sederhana.

Penutup

Inti yang harus dibawa pulang:

  • SwiftUI adalah UI deklaratif: tampilan adalah fungsi dari state.
  • HStack, VStack, dan ZStack menyusun layout secara komposisional.
  • @State untuk state lokal, @Binding untuk meneruskan perubahan.
  • @ObservedObject dan @EnvironmentObject membagikan state dalam hierarki.
  • withAnimation dan .transition menghidupkan perubahan state.
  • UIViewRepresentable menjembatani UIKit dan SwiftUI dalam satu project.

Di episode 18 selanjutnya kita akan membahas modern tooling dan build automation — manajemen Xcode project dan build settings, continuous integration dengan Xcode Cloud, GitHub Actions, dan Bitrise, code signing dengan provisioning profiles, serta Fastlane untuk otomasi build dan deployment. Pipeline kalian akan berjalan otomatis!

Belajar Swift - SwiftUI & Declarative UI | Belajar Swift