Back to skills
SKILL.md
Swiftui Patterns
ASecuritySwiftUI UI patterns, state management, navigation, animations, and performance optimization.
- 65 stars
- 0 votes
- 0 copies
- 3 views
- Added February 7, 2026
Works with
Security analysis
100/100npx -y skills add ahmed3elshaer/everything-claude-code-mobile --skill swiftui-patterns --agent claude-codeAre you the author of Swiftui Patterns?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ahmed3elshaer-swiftui-patterns)---
name: swiftui-patterns
description: SwiftUI UI patterns, state management, navigation, animations, and performance optimization.
---
# SwiftUI Patterns
Modern SwiftUI patterns for iOS 17+ development.
## View Composition
### Small, Focused Views
```swift
// ✅ Good: Single responsibility
struct AvatarView: View {
let imageURL: URL?
let size: CGFloat
var body: some View {
AsyncImage(url: imageURL) { image in
image.resizable()
} placeholder: {
Color.gray.opacity(0.2)
}
.frame(width: size, height: size)
.clipShape(Circle())
}
}
struct UserRow: View {
let user: User
var body: some View {
HStack {
AvatarView(imageURL: user.avatarURL, size: 48)
VStack(alignment: .leading) {
Text(user.name).font(.headline)
Text(user.email).font(.caption).foregroundStyle(.secondary)
}
}
}
}
```
## State Management
### @Observable (iOS 17+)
```swift
@Observable
class HomeViewModel {
var items: [Item] = []
var isLoading = false
func loadItems() async {
isLoading = true
items = await api.fetchItems()
isLoading = false
}
}
struct HomeView: View {
@State private var viewModel = HomeViewModel()
var body: some View {
List {
if viewModel.isLoading {
ProgressView()
} else {
ForEach(viewModel.items) { item in
Text(item.title)
}
}
}
.task {
await viewModel.loadItems()
}
}
}
```
## Performance Patterns
### Lazy Containers
```swift
// ✅ LazyVStack for long lists
ScrollView {
LazyVStack(spacing: 16) {
ForEach(items) { item in
ItemCard(item: item)
}
}
}
// ✅ LazyHStack for horizontal lists
ScrollView(.horizontal) {
LazyHStack(spacing: 12) {
ForEach(users) { user in
UserAvatar(user: user)
}
}
}
```
### Equatable Views
```swift
struct ItemRow: View, Equatable {
let item: Item
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.item.id == rhs.item.id
}
var body: some View {
HStack {
Text(item.title)
Text(item.price)
}
}
}
```
## Navigation
### NavigationStack
```swift
enum Route: Hashable {
case home
case detail(String)
case profile(userId: String)
}
struct AppNavigation: View {
@State private var path: [Route] = []
var body: some View {
NavigationStack(path: $path) {
HomeView()
.navigationDestination(for: Route.self) { route in
switch route {
case .home:
HomeView()
case .detail(let id):
DetailView(id: id)
case .profile(let userId):
ProfileView(userId: userId)
}
}
}
}
}
```
### Sheet Presentation
```swift
struct RootView: View {
@State private var presentedItem: Item?
@State private var showingSettings = false
var body: some View {
List(items) { item in
Button(item.title) { presentedItem = item }
}
.sheet(item: $presentedItem) { item in
DetailSheet(item: item)
}
.sheet(isPresented: $showingSettings) {
SettingsView()
}
}
}
```
## Gestures
### Custom Gestures
```swift
struct SwipeToDismiss: ViewModifier {
@State private var offset: CGFloat = 0
func body(content: Content) -> some View {
content
.offset(x: offset)
.gesture(
DragGesture()
.onChanged { value in
if value.translation.width < 0 {
offset = value.translation.width
}
}
.onEnded { value in
if value.translation.width < -100 {
// Dismiss action
}
offset = 0
}
)
}
}
```
## Animations
### Spring Animations
```swift
struct AnimatedButton: View {
@State private var isPressed = false
var body: some View {
Circle()
.fill(isPressed ? Color.blue : Color.gray)
.frame(width: 80, height: 80)
.scaleEffect(isPressed ? 0.9 : 1.0)
.animation(.spring(response: 0.3, dampingFraction: 0.6), value: isPressed)
.onTapGesture {
withAnimation {
isPressed.toggle()
}
}
}
}
```
### Phase Animations
```swift
struct StaggerAnimation: View {
let items: [String]
var body: some View {
VStack {
ForEach(Array(items.enumerated()), id: \.offset) { index, item in
Text(item)
.transition(.scale.combined(with: .opacity))
}
}
}
}
// Usage with stagger
.transition(.asymmetric(
insertion: .scale.combined(with: .opacity),
removal: .opacity
))
```
## Custom Modifiers
```swift
struct CardModifier: ViewModifier {
var backgroundColor: Color = .white
var cornerRadius: CGFloat = 12
var shadowRadius: CGFloat = 4
func body(content: Content) -> some View {
content
.padding()
.background(backgroundColor)
.clipShape(RoundedRectangle(cornerRadius: cornerRadius))
.shadow(radius: shadowRadius)
}
}
extension View {
func cardStyle(
backgroundColor: Color = .white,
cornerRadius: CGFloat = 12,
shadowRadius: CGFloat = 4
) -> some View {
modifier(CardModifier(
backgroundColor: backgroundColor,
cornerRadius: cornerRadius,
shadowRadius: shadowRadius
))
}
}
```
## Shapes & Styles
### Custom Shapes
```swift
struct BlobShape: Shape {
var cornerRadius: CGFloat = 40
var animatableData: CGFloat = cornerRadius
func path(in rect: CGRect) -> Path {
var path = Path()
let points = [
CGPoint(x: 0, y: 0),
CGPoint(x: rect.width, y: 0),
CGPoint(x: rect.width, y: rect.height),
CGPoint(x: 0, y: rect.height)
]
// Create blob shape
return path
}
}
// Usage
BlobShape(cornerRadius: 50)
.fill(Color.blue.gradient)
```
### Gradients
```swift
Circle()
.fill(
LinearGradient(
colors: [.blue, .purple],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
// Angular gradient
Circle()
.fill(AngularGradient(
colors: [.red, .yellow, .green, .blue, .red],
center: .center
))
```
## Grid Layouts
```swift
LazyVGrid(
columns: [
GridItem(.adaptive(minimum: 100), spacing: 16)
],
spacing: 16
) {
ForEach(items) { item in
ItemCell(item: item)
}
}
```
---
**Remember**: SwiftUI views are values. Compose them, transform them, and let the framework handle rendering.
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.