SwiftUI View patterns with QrewTheme, three-state rendering, and RTL support
Use this skill when building or editing SwiftUI Views in QrewNFCBusinessCards/Views/.
import SwiftUI
struct MyFeatureView: View {
let authVM: AuthViewModel
let lang: LanguageManager
@State private var vm = MyFeatureViewModel()
var body: some View {
NavigationStack {
ZStack {
QrewTheme.background.ignoresSafeArea()
if vm.isLoading && vm.items.isEmpty {
loadingView
} else if let error = vm.errorMessage, vm.items.isEmpty {
errorView(error)
} else if vm.items.isEmpty {
emptyState
} else {
contentView
}
}
.environment(\.layoutDirection, lang.layoutDirection)
.navigationTitle(lang.localized(ar: "العنوان", en: "Title"))
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button { /* action */ } label: {
Image(systemName: "plus")
.foregroundStyle(QrewTheme.accent)
}
}
}
.task { await vm.loadData(userId: authVM.currentUser?.id ?? "") }
.sheet(isPresented: $vm.showSheet) { /* modal */ }
}
}
}
QrewTheme.background.ignoresSafeArea() as base.task async — use .task { await ... } for data loading, NOT .onAppear.environment(\.layoutDirection) — pass lang.layoutDirection for RTLlang.localized(ar:en:) — all visible text must be bilingualloadingView, emptyState, contentView as computed properties.background(QrewTheme.cardBackground, in: .rect(cornerRadius: 12)).overlay(RoundedRectangle(cornerRadius: 12).stroke(QrewTheme.border.opacity(0.5), lineWidth: 1))| What | Where |
|---|---|
| Full View template | references/view-anatomy.md |
| QrewTheme colors | references/qrewtheme.md |
| Three-state pattern | references/three-state.md |
| RTL layout | references/rtl-layout.md |
QrewNFCBusinessCards/Views/QrewNFCBusinessCards/ViewModels/QrewNFCBusinessCards/Utilities/QrewTheme.swiftQrewNFCBusinessCards/Utilities/LanguageManager.swift