Agent skills for iOS, iPadOS, Swift, SwiftUI, and modern Apple framework development.
71
89%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
Use a centralized sheet routing pattern so any view can present modals without prop-drilling. This keeps sheet state in one place and scales as the app grows.
SheetDestination enum that describes every modal and is Identifiable.presentedSheet: SheetDestination?).withSheetDestinations(...) that maps the enum to concrete sheet views.presentedSheet directly.enum SheetDestination: Identifiable, Hashable {
case composer
case editProfile
case settings
case report(itemID: String)
var id: String {
switch self {
case .composer, .editProfile:
// Use the same id to ensure only one editor-like sheet is active at a time.
return "editor"
case .settings:
return "settings"
case .report:
return "report"
}
}
}extension View {
func withSheetDestinations(
sheet: Binding<SheetDestination?>
) -> some View {
sheet(item: sheet) { destination in
Group {
switch destination {
case .composer:
ComposerView()
case .editProfile:
EditProfileView()
case .settings:
SettingsView()
case .report(let itemID):
ReportView(itemID: itemID)
}
}
}
}
}struct StatusRow: View {
@Environment(RouterPath.self) private var router
var body: some View {
Button("Report") {
router.presentedSheet = .report(itemID: "123")
}
}
}For the child view to work, a parent view must:
withSheetDestinations(sheet: $router.presentedSheet) (or an equivalent sheet(item:) handler), and.environment(router) after the sheet modifier so the modal content inherits it.This makes the child assignment to router.presentedSheet drive presentation at the root.
Wrap sheet content in a NavigationStack so it can push within the modal.
struct NavigationSheet<Content: View>: View {
var content: () -> Content
var body: some View {
NavigationStack {
content()
.toolbar { CloseToolbarItem() }
}
}
}sheet(item:) to guarantee a single sheet is active and to drive presentation from the enum.id when they are mutually exclusive (e.g., editor flows).Control sheet dimensions with presentationSizing(_:) (iOS 18+):
.sheet(item: $selectedItem) { item in
EditItemSheet(item: item)
.presentationSizing(.form)
}PresentationSizing values:
.automatic -- platform default.page -- roughly paper size, for informational content.form -- slightly narrower than page, for form-style UI.fitted -- sized by the content's ideal sizeModifier methods for fine-tuning:
.fitted(horizontal:vertical:) -- constrain fitting to specific axes.sticky(horizontal:vertical:) -- grow but do not shrink in specified dimensionsShow a confirmation dialog when the user tries to dismiss a sheet with unsaved changes:
.sheet(item: $selectedItem) { item in
EditItemSheet(item: item)
.dismissalConfirmationDialog(
"Discard changes?",
shouldPresent: hasUnsavedChanges
) {
Button("Discard", role: .destructive) { discardChanges() }
}
}.keyboardShortcut(.defaultAction) to set the default buttonsheet(isPresented:) and sheet(item:) for the same concern; prefer a single enum.SheetDestination; pass lightweight identifiers or models.id values.presentationSizing(.form) for form sheets instead of hard-coding frame dimensions.dismissalConfirmationDialog with a shouldPresent condition; showing it when there are no changes is confusing.skills
accessorysetupkit
references
activitykit
references
adattributionkit
references
alarmkit
references
app-clips
app-intents
references
app-store-optimization
app-store-review
apple-on-device-ai
appmigrationkit
references
audioaccessorykit
references
authentication
references
avkit
references
background-processing
references
browserenginekit
references
callkit
references
carplay
references
cloudkit
references
contacts-framework
references
core-bluetooth
references
core-data
core-motion
references
core-nfc
references
coreml
references
cryptokit
references
cryptotokenkit
references
debugging-instruments
device-integrity
references
dockkit
references
energykit
references
eventkit
references
financekit
references
focus-engine
gamekit
references
healthkit
references
homekit
references
ios-accessibility
ios-localization
ios-networking
ios-simulator
references
mapkit
metrickit
references
musickit
references
natural-language
references
paperkit
references
passkit
references
pdfkit
references
pencilkit
references
permissionkit
references
photokit
push-notifications
realitykit
references
relevancekit
references
scenekit
references
sensorkit
references
speech-recognition
spritekit
references
storekit
swift-api-design-guidelines
swift-architecture
swift-charts
references
swift-codable
swift-concurrency
swift-formatstyle
swift-language
swift-security
references
swift-testing
swiftdata
swiftlint
swiftui-animation
swiftui-gestures
references
swiftui-layout-components
swiftui-liquid-glass
references
swiftui-patterns
swiftui-performance
swiftui-uikit-interop
swiftui-webkit
tabletopkit
references
tipkit
references
vision-framework
weatherkit
references
widgetkit
references