#30DaysOfSwiftUI Day 3: Building Dynamic User Interactions with SwiftUI Controls
Pada hari ketiga dari #30DaysOfSwiftUI, kita akan berfokus pada bagaimana menghandle interaksi pengguna yang dinamis menggunakan berbagai kontrol yang terdapat pada SwiftUI. Kontrol-kontrol ini memungkinkan pengguna untuk berinteraksi dengan aplikasi kita secara aktif, seperti mengisi form, memilih pilihan, ataupun slider.
Apa yang Akan Kita Pelajari?
- Memahami Controls yang terdapat pada SwiftUI seperti input pengguna, termasuk
TextField
,Toggle
, danPicker
. - Memahami bagaimana mengelola interaksi pengguna dan data binding.
- Memahami bagaimana membuat UI yang dinamis dengan merespons input pengguna menggunakan Controls SwiftUI.
A. TextField
TextField
adalah salah satu kontrol yang paling umum digunakan dalam SwiftUI untuk memungkinkan user memasukkan teks atau input ke dalam aplikasi. Dengan menggunakan text field, kita dapat dengan mudah membuat form, kotak pencarian, atau bagian lain dari antarmuka user yang memerlukan inputan teks.
Penggunaan text fields
Pada saat pembuatan text field, sebenarnya kita memberikan label dan binding ke suatu nilai. Jika nilai tersebut adalah string, maka text field akan terus memperbarui nilai ini saat pengguna mengetik atau mengedit teks dalam bidang tersebut. Sedakna untuk tipe non-string, text field akan memperbarui nilai ketika pengguna menyelesaikan editan mereka, seperti menekan tombol Return pada keyboard.
Contoh berikut menunjukkan sebuah text field untuk menerima username, dan sebuah text view di bawahnya yang mengikuti nilai username secara terus-menerus. Text view ini akan berubah warna saat pengguna sedang ataupun telah mengakhiri pengeditan.
@State private var username: String = ""
@FocusState private var emailFieldIsFocused: Bool
var body: some View {
TextField(
"User name (email address)",
text: $username
)
.focused($emailFieldIsFocused)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.border(.secondary)
Text(username)
.foregroundColor(emailFieldIsFocused ? .red : .blue)
}
Text field prompts
Kita dapat mengatur prompts eksplisit pada text field untuk membimbing user tentang teks apa yang harus diinput. Ini sangat berguna untuk memberikan panduan kepada user, terutama dalam situasi di mana bidang text field harus diisi.
Contoh:
Pada form register, user diwajibkan untuk mengisi form username dan password. Kita dapat menggunakan prompt untuk menunjukkan bahwa kedua form tersebut wajib diisi, seperti berikut:
Form {
TextField(text: $username, prompt: Text("Required")) {
Text("Username")
}
SecureField(text: $password, prompt: Text("Required")) {
Text("Password")
}
}
Dalam contoh ini, prompt “Required” digunakan untuk memberikan petunjuka bahwa kedua form itu harus diisi sebelum user dapat melanjutkan menggunakan aplikasi.
Styling text fields
Kita dapat menyesuaikan tampilan dan interaksi dari TextField
menggunakan modifier textFieldStyle(...)
, dengan memasukan instance dari TextFieldStyle
. Contoh berikut menerapkan style roundedBorder
pada text field.
TextField(text: $username, prompt: Text("Required")) {
Text("Username")
}.textFieldStyle(.roundedBorder)
B. Toggle
Toggle adalah kontrol UI yang memungkinkan pengguna untuk memilih antar dua opsi biner, seperti on/off, ya/tidak, ataupun aktif/nonaktif. Dalam SwiftUI, kita dapat menggunakan view Toggle
untuk membuat toggle.
Penggunaan toggle
Kita dapat menambahkan toggle ke tampilan aplikasi dengan menggunakan syntax berikut:
Toggle("Enable Feature", isOn: $isToogled)
.padding()
Di sini, “Enable Feature” adalah label yang akan ditampilkan bersama dengan Toogle, dan $isToggled
adalah binding ke nilai boolean yang akan menentukan apakah toggle sedang aktif atau tidak.
Handling toggle
Ketika pengguna mengubah status toggle, nilai yang dibinding $isToggled
akan diperbarui secara otomatis. Maka dengan itu kita dapat menangani perubahan ini dengan menambahkan logika yang sesuai ke dalam blok body atau kita dapat juga menggunakan modifier .onChanged(...)
untuk melakukan tindakan tertentu setiap kali nilai toggle berubah.
Misalkan kita user untuk mengaktifkan atau menonaktifkan fitur dalam aplikasi kita. Berikut contoh kodenya:
Toggle("Enable Feature", isOn: $isFeatureEnabled)
.padding()
if isFeatureEnabled {
Text("Feature is enabled!")
.padding()
} else {
Text("Feature is disabled.")
.padding()
}
C. Picker
Picker adalah kontrol UI yang memungkinkan user untuk memilih satu nilai dari beberapa opsi yang tersedia. Dalam SwiftUI, picker digunakan untuk menyediakan antarmuka pengguna yang interaktif untuk memilih nilai dari serangkaian opsi yang ada.
Picker("Choose on option", selection: $selectedOptionIndex) {
ForEach(0 ..< options.count) {
Text(options[$0])
}
}
.pickerStyle(SegmentedPickerStyle())
Text("Selected Option: \(options[selectedOptionIndex])")
Pada contoh di atas “Choose an option” adalah label yang akan ditampilkan bersama dengan Picker, sedangkan selectedOptionIndex
adalah binding ke nilai yang dipilih dalam bentuk index dari opsi-opsi yang tersedia.
D. Menangani interaksi user dan data binding
Dalam pengembangan aplikasi, menangani interaksi user dan data binding adalah aspek penting untuk memastikan pengalaman user yang responsif dan berinteraksi. Dalam SwiftUI, kita dapat dengan mudah menangani interaksi user dan data binding menggunakan berbagai kontrol UI dan modifier yang disediakan. Berikut cara-cara untuk menangani interaksi user:
Actions Modifier
Kita dapat menambahkan modifier actions seperti .onTapGesture
atau .onTap
ke tampilan untuk menangani interaksi user seperti ketika tampilan diklik, Contoh:
Text("Tap Me")
.onTapGesture {
// Handle user tap here
}
State Modifier
Properti @State
digunakan untuk mengelola state lokal dalam sebuah view. Ketika kita menandai sebuah properti dengan @State
, SwiftUI akan secara otomatis memantau perubahan pada nilai tersebut dan merender ulang view jika terjadi perubahan. Sebelumnya properti udah sering digunakan dari awal materi ini untuk mengelola data binding dari kontrol UI.
Berikut contoh aplikasi catatan sederhana di mana pengguna dapat menambahkan catatan baru dan menghapus catatan yang ada:
struct ContentView: View {
@State private var notes: [String] = []
@State private var newNote: String = ""
var body: some View {
VStack {
TextField("Add a new note", text: $newNote)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
Button("Add Note") {
if !newNote.isEmpty {
notes.append(newNote)
newNote = ""
}
}
.padding()
List {
ForEach(notes, id: \.self) { note in
Text(note)
}
.onDelete { indices in
notes.remove(atOffsets: indices)
}
}
.padding()
}
.navigationTitle("Notes")
}
}
Pada contoh di atas, user dapat menambahkan note baru menggunakan text field dan tombol “Add Note”. Note baru ditambahkan ke daftar dan ditampilkan dalam List. User juga dapat menghapus note dengan menggeser ke dari kanan ke kiri pada note yang ada di List.
Tambahan
Beberapa hal yang penting mengenai @State
:
- Penanda perubahan state: Properti yang ditandai dengan
@State
merupakan penanda bahwa nilai dari properti tersebut dapat berubah. Ketika nilai berubah, SwiftUI akan secara otomatis memperbarui UI yang terkait dengan properti tersebut. - Hanya untuk view spesifik:
@State
digunakan untuk menyimpan state lokal yang hanya relevan untuk satu view tertentu. Properti yang ditandai dengan@State
akan di-reset ke nilai awalnya setiap kali view tersebut dirender ulang. - Hanya digunakan pada
struct
:@State
hanya dapat digunakan padastuct
karena SwiftUI akan mengelola state lokal ini secara internal dengan menggunakan konsep boxed value. Hal ini memungkinkan properti@State
untuk berubah tanpa mengubah identitas struktur view. - Penggunaan dalam modifier dan binding: Properti yang ditandai dengan
@State
sering diguunakan dalam modifier seperti@Binding
,@ObservedObject
, dan@EnvironmentObject
untuk mengikat dan memantau nilai state antar view.