Главне тачке
View Protocol је централни протокол SwiftUI-ја. Захтева само једно својство: var body: some View. body је израчунато својство које враћа опис UI-ја. SwiftUI позива body при свакој промени стања и рендерује резултат на GPU-у.
@ViewBuilder је Result Builder за Views. Омогућава писање више Views унутар затварања без return-а и без TupleView-а. Подржава if/else, switch, ForEach. Сви контејнери (VStack, HStack, ZStack, Group) користе @ViewBuilder. Алтернатива је Group { … } за груписање без распореда. some View је Opaque Type. Компајлер зна конкретан тип View (Text, Button, VStack, итд.), али га споља враћа као some View. Ово омогућава промену типа body-ја без промене потписа. ViewModifier — модификатор View: .font(), .padding(), .background(). Прилагођени модификатор кроз ViewModifier протокол и .modifier().
// Пример View са @ViewBuilder и NavigationStack
struct ContentView: View {
@State private var items = ["Item 1", "Item 2"]
var body: some View {
NavigationStack {
List(items, id: .self) { item in
NavigationLink(item) {
DetailView(item: item)
}
}
.navigationTitle("Items")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Add") {
items.append("New Item")
}
}
}
}
}
}
// DetailView са @StateObject
struct DetailView: View {
let item: String
@StateObject private var viewModel = DetailViewModel()
var body: some View {
Text(item)
.task {
await viewModel.loadDetails(for: item)
}
}
}NavigationStack (iOS 16+) — навигација вођена подацима. Прима путању (низ hashable вредности) и приказује одредиште кроз navigationDestination. Замењује NavigationLink са одредишним приказима. NavigationLink — дугме за навигацију стеком. List — вертикална листа са секцијама, превлачењима, брисањем и превлачењем и испуштањем. Form — специјализована List за подешавања: секције, бирачи, прекидачи, текстуална поља. Section — груписање у List/Form са заглављем и подножјем. ViewModifier — прилагођени модификатори за поновну употребу стилова. .modifier(CustomModifier()) — примена.
List у SwiftUI-ју је еквивалент UITableView-а. Подржава .onDelete, .onMove, .refreshable. SwipeActions — .swipeActions { Button("Обриши", role: .destructive) { } }. Form — оптимизован за подешавања: DatePicker, Toggle, Stepper, Picker. Section са header/footer-ом — за груписање. OutlineGroup — хијерархијске листе (еквивалент UITableView-а са секцијама). DisclosureGroup — склопива секција са садржајем. IT Sectr препоручује List за податке и Form за подешавања.
PreviewProvider — протокол за прегледе у Xcode Canvas-у. Canvas — интерактивни преглед SwiftUI-ја (захтева @main и Swift 5.9+). @ScaledMetric — прилагодљива величина која се скалира са Dynamic Type-ом.
Property Wrappers су основа управљања стањем у SwiftUI-ју. @State — локално стање (тип вредности). @Binding — веза са стањем родитеља. @StateObject — креира ObservableObject. SwiftUI управља животним циклусом објекта. @ObservedObject — посматра спољашњи ObservableObject. @EnvironmentObject — објекат из окружења (убацивање зависности кроз .environmentObject()). @Environment — системске вредности (.colorScheme, .locale). @AppStorage — UserDefaults. @FetchRequest — Core Data упит. @FocusState — фокус уноса.
| Омотач | Намена | Власништво |
|---|---|---|
| @State | Локално стање (тип вредности) | View поседује |
| @Binding | Веза са стањем родитеља | Родитељ поседује |
| @StateObject | Креира ObservableObject | View поседује |
| @ObservedObject | Посматра спољашњи објекат | Спољашњи власник |
| @EnvironmentObject | Објекат из окружења | Предак поседује |
| @Environment | Системска вредност | Систем |
| @AppStorage | UserDefaults | UserDefaults |
| @FocusState | Фокус уноса | View поседује |
@StateObject против @ObservedObject: @StateObject креира објекат, @ObservedObject га посматра. Користите @StateObject за прво креирање модела у хијерархији, @ObservedObject за прослеђивање дечјим приказима. @FocusState — управљање фокусом: .focused($field, equals: .email). Подржава enum за више поља.
@Environment — системске вредности: colorScheme, locale, sizeCategory, layoutDirection, managedObjectContext. Прилагођене вредности окружења — прилагођена вредност кроз EnvironmentKey. Користи се за убацивање зависности: пренос сервиса без експлицитних параметара. Модификатор .environment() — поставља вредност у хијерархији. @EnvironmentObject — ObservableObject из .environmentObject(). Разликује се од @Environment по томе што преноси референтни тип. IT Sectr препоручује @Environment за системске вредности и @EnvironmentObject за сервисе.
.task{} — асинхрона операција при појави приказа. Аутоматско отказивање при нестанку. Замена за .onAppear за async/await. .onAppear{} — синхрона операција при појави. .onDisappear{} — операција при нестанку. .onChange(of:) — реакција на промене вредности. .onReceive(Publisher) — реакција на Combine publisher. Животни циклус View-а у SwiftUI-ју: init → onAppear → body (рендеровање) → onDisappear. При промени стања: body → diff → поновно рендеровање. IT Sectr препоручује .task за асинхроно учитавање и .onAppear за аналитику.
.animation() — модификатор анимације. .transition() — анимација појаве/нестанка. withAnimation — експлицитна анимација промена стања. matchedGeometryEffect — анимација између различитих приказа (hero animation). PhaseAnimator (iOS 17+) — вишефазна анимација заснована на enum-у. KeyframeAnimator (iOS 17+) — анимација кадар по кадар са кључним кадровима. SwiftUI анимације се извршавају на GPU-у кроз Core Animation. IT Sectr препоручује .spring() за природне анимације и .interpolatingSpring за физичке ефекте.
ObservableObject — протокол за објекте са @Published својствима. SwiftUI се претплаћује на objectWillChange publisher. @Published — објављује промене својства. @StateObject — креира ObservableObject, управља животним циклусом. @ObservedObject — посматра спољашњи. Combine — оквир за реактивно програмирање. @EnvironmentObject — DI кроз окружење. .environmentObject() поставља, @EnvironmentObject чита. MVVM — стандардна архитектура: View (SwiftUI) — ViewModel (ObservableObject) — Model. IT Sectr препоручује MVVM + @StateObject за главне ViewModel-е.
class UserViewModel: ObservableObject {
@Published var users: [User] = []
@Published var isLoading = false
func loadUsers() async {
isLoading = true
defer { isLoading = false }
do {
users = try await api.fetchUsers()
} catch {
print("Грешка: \(error)")
}
}
}
struct UsersView: View {
@StateObject private var viewModel = UserViewModel()
var body: some View {
List(viewModel.users, id: \.id) { user in
Text(user.name)
}
.task { await viewModel.loadUsers() }
.overlay {
if viewModel.isLoading { ProgressView() }
}
}
}Приступачност у SwiftUI-ју: .accessibilityLabel(), .accessibilityHint(), .accessibilityValue(), .accessibilityAddTraits(). VoiceOver чита ознаке приступачности. Dynamic Type — @ScaledMetric, @DynamicProperty. Локализација: String(localized:) (SwiftUI + String Catalog). LocalizedStringKey — аутоматски превод. Правила множине — кроз String Catalog (one, few, many, other). С десна на лево (арапски, хебрејски) — аутоматски подржано. .environment(.layoutDirection, .rightToLeft). IT Sectr препоручује ознаке приступачности за све интерактивне елементе.
struct AccessibleButton: View {
let action: () -> Void
var body: some View {
Button(action: action) {
Label("Settings", systemImage: "gear")
}
.accessibilityLabel("Open Settings")
.accessibilityHint("Double tap to navigate to settings screen")
.accessibilityAddTraits(.isButton)
}
}
// Подршка за Dynamic Type
struct ScalableText: View {
@ScaledMetric private var fontSize: CGFloat = 17
var body: some View {
Text("Hello, World!")
.font(.system(size: fontSize))
}
}Swift Charts (iOS 16+) — оквир за изградњу графикона. Chart { } — основни контејнер. BarMark, LineMark, PointMark, AreaMark, RuleMark — ознаке. ForEach за податке. ChartAxis — прилагођавање оса. .chartXAxis, .chartYAxis. ChartLegend — легенда. Интерполација — catmullRom, linear, step. Анимација — .animation() за Chart. IT Sectr препоручује Swift Charts за уграђене графиконе и Charts (DGCharts) за сложене.
import Charts
struct MonthlySales: Identifiable {
let id = UUID()
let month: String
let sales: Double
}
struct SalesChart: View {
let data: [MonthlySales]
var body: some View {
Chart(data) { item in
BarMark(
x: .value("Month", item.month),
y: .value("Sales", item.sales)
)
.foregroundStyle(.blue.gradient)
}
.chartXAxisLabel("Month")
.chartYAxisLabel("Sales")
.frame(height: 200)
.padding()
}
}Swift Package Manager (SPM) — Apples-ов менаџер зависности. Интегрисан у Xcode. Подржава: бинарне пакете, ресурсе, тестове, swift-6 строгу конкурентност. Објављивање пакета кроз GitHub са semver ознаком. SPM је де факто стандард за Swift зависности, замењујући CocoaPods и Carthage. IT Sectr препоручује SPM за све нове пројекте.
Swift Concurrency (async/await, TaskGroup, AsyncSequence) — async/await уграђени у Swift 5.5+. Task — јединица асинхроности. TaskGroup — паралелни задаци. AsyncSequence — асинхрони низ (AsyncStream, AsyncAlgorithms). Task Local Values — контекстуални подаци за Task. Swift Concurrency у потпуности замењује Combine за асинхроне операције.
Често постављана питања
View Protocol је основни протокол. Захтева var body: some View. body је опис UI-ја рендерован на GPU-у.
@ViewBuilder је Result Builder за вишеструке Views. Омогућава if/else, switch, ForEach у контејнерима.
@StateObject креира објекат. @ObservedObject посматра постојећи. @StateObject за прво креирање у хијерархији.
NavigationStack — навигација вођена подацима. path-based, deep linking. Замењује NavigationView.
@FocusState — управљање фокусом уноса. Модификатор .focused(). Подржава enum за више поља.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.