---
description: This rule explains SwiftUI patterns and best practices for iOS, macOS, watchOS, and tvOS development.
globs: **/*.swift
alwaysApply: false
---
# SwiftUI rules
- Use structs for views and keep them small and focused
- Use @State for simple view-local state
- Use @ObservableObject with @Published for shared state
- Use @Binding to pass mutable state to child views
- Create custom ViewModifiers for reusable styling
- Use environment objects for dependency injection
- Use LazyVStack and LazyHStack for large collections
- Extract complex view logic into separate components
The SwiftUI rule provides guidance on best practices and patterns for developing applications using SwiftUI across Apple platforms, including iOS, macOS, watchOS, and tvOS. It helps maintain consistent, efficient code when working with Apple's declarative UI framework.
This rule serves as a reference guide for SwiftUI development, offering recommendations for structuring views, managing state, and implementing common patterns. It encapsulates essential best practices that help developers write clean, maintainable SwiftUI code while avoiding common pitfalls.
The rule covers several core aspects of SwiftUI development:
The rule emphasizes using structs for views and keeping them small and focused on specific UI components. This approach improves code readability and makes maintenance easier by following the single responsibility principle.
SwiftUI offers several ways to handle state, and this rule provides guidance on when to use each approach:
@State
for simple view-local state that doesn't need to be shared@ObservableObject
with @Published
properties for shared state across multiple views@Binding
for passing mutable state to child viewsThe rule recommends creating custom ViewModifier
s for reusable styling, which helps maintain consistency across your app while reducing code duplication.
For large collections of views, the rule suggests using LazyVStack
and LazyHStack
to improve performance by loading views only as needed.
The SwiftUI rule (swiftui.mdc
) is automatically attached when working with Swift files in Cursor. The rule uses the glob pattern **/*.swift
, which means it will be automatically applied whenever you're editing any Swift file in your project.
This automatic activation provides several benefits:
You don't need to manually invoke this rule since it attaches automatically to Swift files. However, if you want to explicitly reference it in a conversation with the AI, you can type @swiftui
in the chat or Cmd-K interface.
When deciding which state management approach to use, consider the scope and sharing requirements:
// For simple view-local state
struct CounterView: View {
@State private var count = 0
var body: some View {
Button("Increment: \(count)") {
count += 1
}
}
}
// For shared state across views
class UserSettings: ObservableObject {
@Published var username = ""
@Published var isLoggedIn = false
}
// In your view
struct ProfileView: View {
@ObservedObject var settings: UserSettings
var body: some View {
Text("Hello, \(settings.username)")
}
}
Custom view modifiers make styling more consistent and reusable:
struct PrimaryButtonStyle: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
}
// Usage
Button("Save") { /* action */ }
.modifier(PrimaryButtonStyle())
// Or create an extension
extension View {
func primaryButton() -> some View {
self.modifier(PrimaryButtonStyle())
}
}
For lists with many items, use lazy stacks to improve performance:
ScrollView {
LazyVStack {
ForEach(0..<1000) { index in
Text("Row \(index)")
}
}
}
By following these SwiftUI best practices as outlined in the rule, you'll create more maintainable, performant applications across Apple platforms.