SwiftUI Components Guide
Basic View Components
Text and Typography
// Basic text with different styles
Text("Hello, World!")
.font(.title)
.foregroundColor(.blue)
.fontWeight(.bold)
// Multi-line text with alignment
Text("This is a longer text that spans multiple lines and demonstrates text alignment and formatting options")
.multilineTextAlignment(.center)
.lineLimit(3)
.truncationMode(.tail)
// Text with custom font and styling
Text("Custom Styled Text")
.font(.custom("Helvetica Neue", size: 24))
.foregroundStyle(.linearGradient(
colors: [.blue, .purple],
startPoint: .leading,
endPoint: .trailing
))
Layout Containers
// VStack - Vertical stacking
VStack(alignment: .leading, spacing: 10) {
Text("First Item")
Text("Second Item")
Text("Third Item")
}
.padding()
// HStack - Horizontal stacking
HStack(spacing: 15) {
Image(systemName: "star.fill")
Text("Favorites")
Spacer()
Text("42")
}
.padding()
// ZStack - Overlapping views
ZStack {
Rectangle()
.fill(.blue)
.frame(width: 200, height: 100)
Text("Overlay Text")
.foregroundColor(.white)
.font(.title2)
}
// LazyVStack - Performance optimized
LazyVStack(spacing: 8) {
ForEach(0..<1000, id: \.self) { index in
Text("Item \(index)")
.padding()
.background(.gray.opacity(0.1))
}
}
Interactive Elements
// Button with different styles
Button("Tap Me") {
print("Button tapped!")
}
.buttonStyle(.borderedProminent)
// Custom button with icon
Button(action: {
// Action here
}) {
HStack {
Image(systemName: "plus.circle.fill")
Text("Add Item")
}
.padding()
.background(.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
// Toggle
@State private var isOn = false
Toggle("Enable Feature", isOn: $isOn)
.toggleStyle(.switch)
.padding()
// TextField with validation
@State private var username = ""
TextField("Enter username", text: $username)
.textFieldStyle(.roundedBorder)
.autocapitalization(.none)
.disableAutocorrection(true)
.onChange(of: username) { newValue in
// Validation logic
}
Advanced View Components
Custom Shapes and Graphics
// Custom shape
struct RoundedTriangle: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.midX, y: rect.minY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
path.closeSubpath()
return path
}
}
// Usage
RoundedTriangle()
.fill(.blue)
.frame(width: 100, height: 100)
// Custom progress indicator
struct CircularProgressView: View {
let progress: Double
var body: some View {
ZStack {
Circle()
.stroke(.gray.opacity(0.3), lineWidth: 8)
Circle()
.trim(from: 0, to: progress)
.stroke(.blue, style: StrokeStyle(lineWidth: 8, lineCap: .round))
.rotationEffect(.degrees(-90))
.animation(.easeInOut, value: progress)
}
.frame(width: 60, height: 60)
}
}
Complex Layouts
// Grid layout using LazyVGrid
struct GridView: View {
let columns = [
GridItem(.adaptive(minimum: 150), spacing: 16)
]
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 16) {
ForEach(0..<20, id: \.self) { index in
RoundedRectangle(cornerRadius: 10)
.fill(.blue.opacity(0.3))
.frame(height: 100)
.overlay(
Text("Item \(index)")
.foregroundColor(.white)
)
}
}
.padding()
}
}
}
// TabView with custom styling
struct CustomTabView: View {
@State private var selectedTab = 0
var body: some View {
TabView(selection: $selectedTab) {
Text("First Tab")
.tabItem {
Image(systemName: "house.fill")
Text("Home")
}
.tag(0)
Text("Second Tab")
.tabItem {
Image(systemName: "person.fill")
Text("Profile")
}
.tag(1)
}
.accentColor(.blue)
}
}
Navigation Components
// Navigation with custom back button
NavigationView {
VStack {
Text("Detail View")
}
.navigationTitle("Details")
.navigationBarTitleDisplayMode(.inline)
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("Back") {
// Custom back action
}
}
}
}
// Navigation with programmatic navigation
@State private var isShowingDetail = false
NavigationView {
VStack {
Button("Show Detail") {
isShowingDetail = true
}
}
.navigationTitle("Main")
.navigationDestination(isPresented: $isShowingDetail) {
DetailView()
}
}
Performance Optimizations
// Using @ViewBuilder for complex conditional views
struct ConditionalView: View {
let showDetail: Bool
var body: some View {
VStack {
if showDetail {
DetailContent()
} else {
SimpleContent()
}
}
}
@ViewBuilder
private func DetailContent() -> some View {
VStack(spacing: 10) {
Text("Detailed Information")
Text("More content here")
Text("Even more content")
}
}
@ViewBuilder
private func SimpleContent() -> some View {
Text("Simple View")
}
}
// Lazy loading for expensive views
struct LazyContentView: View {
var body: some View {
ScrollView {
LazyVStack {
ForEach(0..<100, id: \.self) { index in
LazyView {
ExpensiveView(index: index)
}
}
}
}
}
}
// LazyView wrapper for performance
struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
Accessibility
// Making views accessible
Button("Delete Item") {
// Delete action
}
.accessibilityLabel("Delete selected item")
.accessibilityHint("Double tap to confirm deletion")
.accessibilityAddTraits(.isDestructive)
// Custom accessibility actions
Text("Important Information")
.accessibilityAction(named: "Read Aloud") {
// Text-to-speech action
}
.accessibilityAction(named: "Share") {
// Share action
}