一键导入
swiftui-components
Reference for SwiftUI built-in components, layout tools, and visual styling for iOS-native interfaces
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Reference for SwiftUI built-in components, layout tools, and visual styling for iOS-native interfaces
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Strategic search planning for agent-driven research. Generates structured search-term matrices with tiered fallback strategies, engine-specific operators, and grading criteria before executing any searches. Use this skill whenever research requires more than a single search query — comparing technologies, verifying claims across sources, surveying a landscape, investigating a multi-faceted question, or building evidence for a decision. Do NOT use for quick factual lookups, fetching a single known URL, or questions answerable from a single source. Covers tech, academic, regulatory, and general domains. Think of it as "research planning" — the matrix is the plan, execution comes after.
Create language conversion skills for translating code from language A to language B. Use when building 'convert-X-Y' skills, designing type mappings between languages, establishing idiom translation patterns, or defining conversion methodologies. Provides foundational patterns that specific conversion skills extend.
Guide for translating code between programming languages. Use when converting code from one language to another, planning language migrations, understanding conversion challenges, asking about type mappings, idiom translations, or referencing pattern mappings. Covers APTV workflow, type systems, error handling, concurrency, and language-specific gotchas.
Identify skill coverage gaps and improvement opportunities. Use when analyzing missing skills for a task, creating skill gap issues, evaluating skill effectiveness, or refining skill progressive disclosure.
Validate Claude Code skills against best practices. Use when checking skill quality, running validation, or creating improvement issues.
{{DESCRIPTION}}
| name | swiftui-components |
| description | Reference for SwiftUI built-in components, layout tools, and visual styling for iOS-native interfaces |
| tags | ["swift","swiftui","components","layouts","ui","ios"] |
Reference for SwiftUI's built-in components, layout tools, and visual styling for creating polished, iOS-native interfaces.
// Vertical stack
VStack(alignment: .leading, spacing: 12) {
Text("Title")
.font(.headline)
Text("Subtitle")
.font(.subheadline)
.foregroundStyle(.secondary)
}
// Horizontal stack
HStack(spacing: 16) {
Image(systemName: "star.fill")
Text("Featured")
Spacer()
Text("5.0")
}
// Layered stack (back to front)
ZStack(alignment: .bottomTrailing) {
Image("photo")
.resizable()
.aspectRatio(contentMode: .fill)
Text("New")
.padding(8)
.background(.red)
.clipShape(Capsule())
.padding(8)
}
// Adaptive grid - columns adjust to fit
let adaptiveColumns = [
GridItem(.adaptive(minimum: 150, maximum: 200))
]
LazyVGrid(columns: adaptiveColumns, spacing: 16) {
ForEach(items) { item in
ItemCard(item: item)
}
}
// Fixed grid - explicit column count
let fixedColumns = [
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible())
]
LazyVGrid(columns: fixedColumns, spacing: 12) {
ForEach(items) { item in
ItemThumbnail(item: item)
}
}
// Horizontal grid
let rows = [GridItem(.fixed(100)), GridItem(.fixed(100))]
LazyHGrid(rows: rows, spacing: 16) {
ForEach(items) { item in
ItemRow(item: item)
}
}
struct ResponsiveCard: View {
var body: some View {
GeometryReader { geometry in
HStack(spacing: 0) {
// Left side takes 1/3
Image("thumbnail")
.resizable()
.frame(width: geometry.size.width * 0.33)
// Right side takes 2/3
VStack(alignment: .leading) {
Text("Title")
Text("Description")
}
.frame(maxWidth: .infinity)
.padding()
}
}
.frame(height: 120)
}
}
// Reading safe area
GeometryReader { geometry in
VStack {
Text("Top inset: \(geometry.safeAreaInsets.top)")
}
}
// Automatically chooses layout that fits
ViewThatFits {
// Try horizontal first
HStack {
Image(systemName: "star")
Text("Long descriptive label")
Text("Details")
}
// Fall back to vertical if horizontal doesn't fit
VStack {
Image(systemName: "star")
Text("Long descriptive label")
Text("Details")
}
}
List {
// Simple rows
ForEach(items) { item in
Text(item.name)
}
// Sections
Section("Favorites") {
ForEach(favorites) { item in
ItemRow(item: item)
}
}
Section("Recent") {
ForEach(recent) { item in
ItemRow(item: item)
}
}
}
.listStyle(.insetGrouped) // iOS-style grouped list
// Swipe actions
List {
ForEach(items) { item in
ItemRow(item: item)
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
delete(item)
} label: {
Label("Delete", systemImage: "trash")
}
}
.swipeActions(edge: .leading) {
Button {
toggleFavorite(item)
} label: {
Label("Favorite", systemImage: "star")
}
.tint(.yellow)
}
}
}
// Tab-based navigation
TabView {
HomeView()
.tabItem {
Label("Home", systemImage: "house")
}
SearchView()
.tabItem {
Label("Search", systemImage: "magnifyingglass")
}
ProfileView()
.tabItem {
Label("Profile", systemImage: "person")
}
}
// Stack-based navigation (iOS 16+)
NavigationStack {
List(items) { item in
NavigationLink(value: item) {
ItemRow(item: item)
}
}
.navigationTitle("Items")
.navigationDestination(for: Item.self) { item in
ItemDetailView(item: item)
}
}
// Split view (iPad/Mac)
NavigationSplitView {
List(categories, selection: $selectedCategory) { category in
Text(category.name)
}
} detail: {
if let category = selectedCategory {
CategoryDetailView(category: category)
} else {
Text("Select a category")
}
}
Form {
Section("Account") {
TextField("Username", text: $username)
SecureField("Password", text: $password)
}
Section("Preferences") {
Toggle("Notifications", isOn: $notificationsEnabled)
Picker("Theme", selection: $theme) {
Text("System").tag(Theme.system)
Text("Light").tag(Theme.light)
Text("Dark").tag(Theme.dark)
}
Stepper("Font Size: \(fontSize)", value: $fontSize, in: 12...24)
Slider(value: $volume, in: 0...100) {
Text("Volume")
}
}
Section {
DatePicker("Date", selection: $date, displayedComponents: .date)
ColorPicker("Accent Color", selection: $accentColor)
}
}
// Basic usage
Image(systemName: "star.fill")
// With configuration
Image(systemName: "heart.fill")
.symbolRenderingMode(.multicolor)
.font(.title)
// Variable value (iOS 16+)
Image(systemName: "speaker.wave.3.fill", variableValue: volume)
// Symbol effects (iOS 17+)
Image(systemName: "wifi")
.symbolEffect(.variableColor.iterative)
Image(systemName: "arrow.down.circle")
.symbolEffect(.bounce, value: downloadStarted)
// In labels
Label("Downloads", systemImage: "arrow.down.circle")
.labelStyle(.titleAndIcon)
// Drop shadow
Text("Elevated")
.padding()
.background(.white)
.clipShape(RoundedRectangle(cornerRadius: 12))
.shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 4)
// Inner shadow effect
RoundedRectangle(cornerRadius: 12)
.fill(.white)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(.gray.opacity(0.2), lineWidth: 1)
)
// Linear gradient
Rectangle()
.fill(
LinearGradient(
colors: [.blue, .purple],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
// Radial gradient
Circle()
.fill(
RadialGradient(
colors: [.yellow, .orange],
center: .center,
startRadius: 0,
endRadius: 100
)
)
// Angular gradient
Circle()
.fill(
AngularGradient(
colors: [.red, .yellow, .green, .blue, .purple, .red],
center: .center
)
)
// Mesh gradient (iOS 18+)
MeshGradient(
width: 3, height: 3,
points: [
[0, 0], [0.5, 0], [1, 0],
[0, 0.5], [0.5, 0.5], [1, 0.5],
[0, 1], [0.5, 1], [1, 1]
],
colors: [
.red, .orange, .yellow,
.green, .blue, .purple,
.pink, .cyan, .mint
]
)
// Background blur
ZStack {
Image("background")
.resizable()
VStack {
Text("Content")
}
.padding()
.background(.ultraThinMaterial)
.clipShape(RoundedRectangle(cornerRadius: 16))
}
// Material options: .regularMaterial, .thinMaterial, .ultraThinMaterial,
// .thickMaterial, .ultraThickMaterial, .bar
// Custom blur
Image("photo")
.blur(radius: 10)
// Built-in shapes
Circle()
Ellipse()
Rectangle()
RoundedRectangle(cornerRadius: 12)
Capsule()
UnevenRoundedRectangle(
topLeadingRadius: 20,
bottomLeadingRadius: 0,
bottomTrailingRadius: 0,
topTrailingRadius: 20
)
// Custom shape
struct Triangle: Shape {
func path(in rect: CGRect) -> Path {
Path { path in
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()
}
}
}
// Usage
Triangle()
.fill(.blue)
.frame(width: 100, height: 100)
struct AnimatedButton: View {
@State private var isPressed = false
var body: some View {
Button("Tap Me") {
// Action
}
.scaleEffect(isPressed ? 0.95 : 1.0)
.animation(.spring(response: 0.3, dampingFraction: 0.6), value: isPressed)
.onLongPressGesture(minimumDuration: .infinity, pressing: { pressing in
isPressed = pressing
}, perform: {})
}
}
struct ContentView: View {
@State private var showDetails = false
var body: some View {
VStack {
Button("Toggle") {
withAnimation(.spring) {
showDetails.toggle()
}
}
if showDetails {
DetailView()
.transition(.asymmetric(
insertion: .scale.combined(with: .opacity),
removal: .slide
))
}
}
}
}
struct HeroAnimation: View {
@Namespace private var animation
@State private var isExpanded = false
var body: some View {
VStack {
if isExpanded {
ExpandedCard(namespace: animation)
} else {
CompactCard(namespace: animation)
}
}
.onTapGesture {
withAnimation(.spring(response: 0.4, dampingFraction: 0.8)) {
isExpanded.toggle()
}
}
}
}
struct CompactCard: View {
var namespace: Namespace.ID
var body: some View {
RoundedRectangle(cornerRadius: 12)
.fill(.blue)
.matchedGeometryEffect(id: "card", in: namespace)
.frame(width: 100, height: 100)
}
}
struct PulsingDot: View {
var body: some View {
Circle()
.fill(.blue)
.frame(width: 20, height: 20)
.phaseAnimator([false, true]) { content, phase in
content
.scaleEffect(phase ? 1.2 : 1.0)
.opacity(phase ? 0.7 : 1.0)
} animation: { _ in
.easeInOut(duration: 0.8)
}
}
}
.primary, .secondary, .background