SwiftUI — mga pangunahing konsepto, View, State at Data Flow

May-akda: IT Sectr Nai-publish: 2026-02-21 Oras ng pagbabasa: 8 min

SwiftUI — deklaratibong framework ng Apple para sa pagbuo ng mga user interface sa lahat ng platform ng ecosystem, na ipinakilala sa WWDC 2019. Hindi tulad ng imperatibong UIKit na may viewDidLoad at manu-manong pag-update ng screen, inilalarawan ng SwiftUI ang UI bilang koleksyon ng mga simpleng istruktura na sumusunod sa protocol ng View. Ayon sa Swift.org (2025), ang SwiftUI ay ginagamit sa 65% ng mga bagong proyektong nai-publish sa App Store. Awtomatikong pinamamahalaan ng framework ang pag-update ng interface sa pamamagitan ng mekanismo ng State at Data Flow — kapag nagbago ang data, ang View ay muling iginuguhit nang walang manu-manong pagtawag sa reloadData.

Mga Pangunahing Punto

  • SwiftUI — deklaratibong framework ng Apple para sa UI (2019), kung saan ang interface ay inilalarawan gamit ang mga istruktura na sumusunod sa protocol ng View.
  • View — pangunahing building block ng SwiftUI; bawat View ay naglalarawan ng bahagi nito ng screen sa pamamagitan ng computed property body.
  • @State — property wrapper para sa pag-iimbak ng lokal na estado, kapag nagbago ito ay awtomatikong muling iginuguhit ang View.
  • @Binding — dalawang-direksyong koneksyon sa pagitan ng View at data, na nagpapahintulot sa child View na baguhin ang estado ng parent.
  • @ObservedObject at @StateObject — koneksyon sa mga panlabas na modelo ng data sa pamamagitan ng mga klase na sumusunod sa protocol ng ObservableObject.

Ano ang SwiftUI?

SwiftUI — deklaratibong UI framework ng Apple, radikal na naiiba mula sa UIKit. Sa halip na lumikha ng mga controller, view, at manu-manong pamahalaan ang kanilang lifecycle, inilalarawan ng developer ang interface sa anyo ng mga deklarasyon: kung ano ang dapat nasa screen, hindi kung paano ito itatayo. Ang SwiftUI ay batay sa prinsipyo ng reaktibiti: ang interface ay isang function ng estado. Kapag nagbago ang estado (State), awtomatikong muling kinakalkula ng SwiftUI ang body ng lahat ng umaasang View at ina-update lamang ang mga nabagong bahagi ng screen. Ang SwiftUI ay available sa iOS 13+, iPadOS 13+, macOS 10.15+, watchOS 6+, tvOS 13+ at visionOS 1+. Ang code ng SwiftUI ay cross-platform: isang file ay gumagana sa iPhone, iPad, Mac at Apple Watch na may minimal na platform adaptation. Ayon sa Apple WWDC Session 101 (2024), sinasaklaw ng SwiftUI ang higit sa 90% ng mga karaniwang UI pattern ng App Store.

SwiftUI vs UIKit

UIKit — imperatibong framework (2008): gumagawa ang developer ng UIViewController, nag-co-configure ng subviews sa viewDidLoad, nag-i-implement ng delegate/datasource para sa UITableView at ina-update ang screen sa pamamagitan ng reloadData o setNeedsLayout. Pinapalitan ng SwiftUI ang mga controller ng mga simpleng istruktura ng View, mga delegate — ng binding at onChange, Auto Layout — ng HStack/VStack/ZStack na may mga modifier (padding, frame, offset). Ang UIKit ay nangangailangan ng manu-manong pamamahala ng memorya sa pamamagitan ng ARC; SwiftUI — mga istruktura na hindi nangangailangan ng reference counting. Ang pagganap ng SwiftUI ay maihahambing sa UIKit: ang framework ay gumagamit ng diffing algorithm para sa minimal na set ng mga pagbabago. Sa IT Sectr, ang SwiftUI ay ginagamit para sa mga bagong proyekto na may target na iOS 17+; ang mga proyektong may suporta sa iOS 14–15 ay nangangailangan ng UIKit dahil sa limitadong compatibility ng SwiftUI.

Deklaratibong syntax ng SwiftUI

Sa SwiftUI, ang interface ay inilalarawan sa pamamagitan ng ViewBuilder — result builder na nag-transform ng set ng View sa tuple o Group. Ang mga modifier (.padding(), .font(), .foregroundColor()) ay lumilikha ng mga bagong View na may binagong setting, hindi minu-mutate ang orihinal na object. Ang bawat modifier ay nagbabalik ng bagong View, na nagpapahintulot ng chaining. Sinusuportahan ng ViewBuilder ang if/else, switch, ForEach — kondisyonal at cyclical na pag-render nang walang hiwalay na controller. Ang View sa SwiftUI ay value type (struct), na ginagarantiyahan ang predictable na behavior at nag-aalis ng race conditions.

Protocol ng View at computed property body

View — protocol na may isang kinakailangan: computed property body ng uri na some View. Bawat istruktura na sumusunod sa View ay naglalarawan ng bahagi nito ng screen sa body. Ang uri na some View — opaque return type na nagtatago ng konkretong uri ng ibinalik na View (pagsasama ng VStack, HStack, ZStack, Text, Image, atbp.). Ang Swift compiler ay nagdi-deduce ng konkretong uri sa yugto ng compilation, pinapanatili ang pagganap ng direktang tawag nang walang type erasure.

swift
import SwiftUI

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

Ang istruktura na GreetingView ay tumatanggap ng parameter na name at nagpapakita ng dalawang text block sa vertical stack. Ang mga modifier na .font, .foregroundColor, .padding at .background ay nagko-configure ng hitsura. Tinatawag ng SwiftUI ang body sa bawat pagbabago ng input parameters (name) — ang muling pagguhit ay nangyayari lamang para sa mga nabagong bahagi. Sa halimbawa, ginamit ang RoundedRectangle na may .ultraThinMaterial — native blur background na binuo sa SwiftUI.

@State: lokal na estado sa SwiftUI

@State — property wrapper na nagdedeklara ng lokal na estado na pagmamay-ari ng isang View. Awtomatikong pinamamahalaan ng SwiftUI ang memorya ng State: kapag nagbago ang value, ang body ay muling iginuguhit, ngunit para lamang sa mga View na gumagamit ng State na ito. Ang State ay source of truth para sa mga simpleng uri (String, Int, Bool, enum). Huwag gamitin ang @State para sa mga kumplikadong modelo ng data — para sa mga iyon ay nakalaan ang @StateObject at @ObservedObject. Ang State ay dapat na private at nakaimbak sa View mismo, hindi ipinapasa sa pagitan ng mga component.

swift
import SwiftUI

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

Paunang halaga count = 0. Bawat pagpindot ng button ay nag-i-increment ng count; awtomatikong muling iginuguhit ng SwiftUI ang CounterView nang buo (lahat ng View). Sa UIKit, ang katulad na scenario ay mangangailangan ng IBOutlet, IBAction at manu-manong pag-update ng label.text. @State ginagarantiyahan na ang View ay muling iginuguhit lamang kapag nagbago ang partikular na State — ang diffing algorithm ng SwiftUI ay nakakahanap ng minimal na pagbabago sa tree.

@Binding: dalawang-direksyong komunikasyon sa pagitan ng View

@Binding — property wrapper na lumilikha ng dalawang-direksyong koneksyon sa pagitan ng View at data na hindi pagmamay-ari ng View. Ang Binding ay isang reference sa State (o ibang source of truth), na nagpapahintulot sa child View na basahin at baguhin ang value na nakaimbak sa parent. Ang Binding ay tinutukoy ng prefix na $: $count ay nagpapasa ng Binding<Int> sa child View. Kung walang Binding, hindi mababago ng child View ang data ng parent — mababasa lamang nito.

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 ay nagmamay-ari ng State quantity at nagpapasa ng Binding sa pamamagitan ng $quantity. Maaaring baguhin ng StepperControl ang value, at ang quantity sa parent ay awtomatikong nag-si-sync. Ang Binding ay hindi kopya ng data, kundi isang tulay patungo sa source of truth. Gamitin ang @Binding para sa custom na controls, editor at reusable component na dapat magbago ng data ng parent.

@ObservedObject at @StateObject: panlabas na mga modelo ng data

@StateObject — property wrapper para sa paglikha at pagmamay-ari ng instance ng klase na sumusunod sa ObservableObject. Ang View ay lumilikha ng object nang isang beses bawat lifecycle at muling iginuguhit kapag nagbago ang @Published properties nito. @ObservedObject — katulad na wrapper, ngunit ang View ay hindi nagmamay-ari ng object — ang object ay nilikha at nakaimbak sa labas ng View (ipinapasa sa pamamagitan ng initializer). Inirerekomenda ng Apple ang @StateObject para sa source of truth sa hierarchy ng View at @ObservedObject para sa dependency injection.

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("Maligayang pagdating, \(settings.username)!")
                    .font(.headline)
            }
        }
        .padding()
    }
}

UserSettings — ObservableObject na may dalawang @Published properties. Ang ProfileView ay nagmamay-ari ng object sa pamamagitan ng @StateObject. Ang pagbabago ng username o isLoggedIn ay awtomatikong muling iginuguhit ang ProfileView. Ang @Published ay gumagamit ng Combine Publisher para ipaalam sa SwiftUI ang tungkol sa mga pagbabago. Para ipasa ang settings sa child View, gamitin ang @ObservedObject:

Data Flow sa SwiftUI: kumpletong larawan

Tinutukoy ng Apple ang apat na antas ng Data Flow sa SwiftUI: @State (lokal, value type), @Binding (dalawang-direksyon), @StateObject/@ObservedObject (reference type na may ObservableObject), @EnvironmentObject (global, injection sa pamamagitan ng environment). Ang EnvironmentObject ay nagpapahintulot ng pagpapasa ng data sa buong hierarchy ng View nang walang explicit na pagpasa sa initializer. Dagdag pa, ang @AppStorage ay gumagana sa UserDefaults, @SceneStorage — sa state ng scene, @FetchRequest — sa Core Data. Ang pagpili ng antas ng Data Flow ay tumutukoy sa arkitektura ng application: ang mga simpleng screen ay gumagamit ng State/Binding, modular — ObservedObject, malakihang — EnvironmentObject + mga solusyong tulad ng Redux (TCA, Composable Architecture).

Property WrapperPagmamay-ariUriKailan gagamitin
@StateLokalValue (struct, enum)Simpleng estado ng isang View (counter, toggle, text field)
@BindingPanlabasReference sa StateChild View na nagbabago ng data ng parent
@StateObjectPagmamay-ari ng ViewReference (class)Source of truth para sa komplikadong modelo ng data
@ObservedObjectInjectionReference (class)Model na ginawa sa labas ng View (ipinasa sa pamamagitan ng init)
@EnvironmentObjectGlobalReference (class)Data na accessible sa buong hierarchy (authentication, tema)

Mga Madalas Itanong

Ano ang pinagkaiba ng @State sa @StateObject?

@State — para sa value types (struct, enum, String, Int) at lokal na estado ng isang View. Awtomatikong pinamamahalaan ng SwiftUI ang memorya ng State. @StateObject — para sa reference types (class) na sumusunod sa ObservableObject. Ang @StateObject ay nagmamay-ari ng object at muling iginuguhit ang View kapag nagbago ang @Published properties. Para sa simpleng counter gamitin ang @State; para sa mga model na may lohika — @StateObject.

Maaari bang gamitin ang SwiftUI sa UIKit?

Oo, ang SwiftUI ay nag-i-integrate sa UIKit sa pamamagitan ng UIHostingController (SwiftUI sa loob ng UIKit) at UIViewRepresentable (UIKit sa loob ng SwiftUI). Binabalot ng UIHostingController ang SwiftUI View sa UIViewController. Ang UIViewRepresentable ay nagpapahintulot ng paggamit ng UIKit components (MKMapView, WKWebView) sa SwiftUI. Ito ay karaniwang approach para sa migration ng mga proyekto mula UIKit patungo sa SwiftUI.

Ano ang ViewBuilder sa SwiftUI?

ViewBuilder — result builder (Swift 5.1) na nag-transform ng set ng View sa iisang value ng uri na TupleView, Group o ConditionalContent. Ang ViewBuilder ay nagpapahintulot ng pagsulat ng imperatibong if/else at switch sa loob ng deklaratibong body. Kung walang ViewBuilder, kakailanganing magbalik ng AnyView o Group para sa bawat conditional block. Ang ViewBuilder ang dahilan kung bakit hindi kailangan ng comma sa pagitan ng View sa body.

Gumagana ba ang SwiftUI sa lahat ng Apple device?

Oo, sinusuportahan ng SwiftUI ang iOS 13+, iPadOS 13+, macOS 10.15+, watchOS 6+, tvOS 13+ at visionOS 1+. Gayunpaman, ang ilang API ay available lamang sa mga bagong bersyon: halimbawa, navigationStack (iOS 16+), Observable macro (iOS 17+). Para sa backward compatibility, gamitin ang #available at UIKit adaptations.

Paano mag-debug ng SwiftUI applications?

Xcode Debug View Hierarchy ay nagpapakita ng SwiftUI View tree na may mga modifier at frames. Ang tool na SwiftUI Inspector (kanang panel ng Xcode) ay nagpapahintulot ng pagbabago ng modifier sa real-time. Ang self._printChanges() sa body ay nag-lo-log ng mga dahilan ng muling pagguhit. Ang Instruments na may SwiftUI template ay sumusubaybay sa performance ng View at nakakatuklas ng labis na muling pagguhit.

Buod

  • SwiftUI — deklaratibong framework ng Apple para sa UI, kung saan ang interface ay inilalarawan gamit ang mga istruktura ng View na may computed property body (2019).
  • View — value type (struct) na sumusunod sa protocol ng View; ang body ay nagbabalik ng some View sa pamamagitan ng ViewBuilder.
  • @State — lokal na estado para sa value types; kapag nagbago, ang View ay awtomatikong muling iginuguhit.
  • @Binding — dalawang-direksyong koneksyon sa pamamagitan ng $ prefix; child View ay nagbabago ng data ng parent.
  • @StateObject / @ObservedObject — reference types na may ObservableObject at @Published properties; StateObject ay nagmamay-ari ng object, ObservedObject ay tumatanggap mula sa labas.
  • @EnvironmentObject — global na estado para sa buong hierarchy ng View; ini-inject sa pamamagitan ng .environmentObject().
  • Data Flow sa SwiftUI — mula sa State (lokal) sa pamamagitan ng Binding (dalawang-direksyon) patungo sa ObservedObject (modular) at EnvironmentObject (global).

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din