mirror of
https://github.com/Dimillian/Skills.git
synced 2026-03-25 08:55:54 +00:00
Introduces the 'swiftui-ui-patterns' skill to docs/skills.json, providing best practices and example-driven guidance for building SwiftUI views and components. Adds SKILL.md and a comprehensive set of reference files covering TabView, NavigationStack, sheets, forms, controls, grids, overlays, haptics, focus handling, media, matched transitions, split views, and more.
2.3 KiB
2.3 KiB
ScrollView and Lazy stacks
Intent
Use ScrollView with LazyVStack, LazyHStack, or LazyVGrid when you need custom layout, mixed content, or horizontal/ grid-based scrolling.
Core patterns
- Prefer
ScrollView+LazyVStackfor chat-like or custom feed layouts. - Use
ScrollView(.horizontal)+LazyHStackfor chips, tags, avatars, and media strips. - Use
LazyVGridfor icon/media grids; prefer adaptive columns when possible. - Use
ScrollViewReaderfor scroll-to-top/bottom and anchor-based jumps. - Use
safeAreaInset(edge:)for input bars that should stick above the keyboard.
Example: vertical custom feed
@MainActor
struct ConversationView: View {
private enum Constants { static let bottomAnchor = "bottom" }
@State private var scrollProxy: ScrollViewProxy?
var body: some View {
ScrollViewReader { proxy in
ScrollView {
LazyVStack {
ForEach(messages) { message in
MessageRow(message: message)
.id(message.id)
}
Color.clear.frame(height: 1).id(Constants.bottomAnchor)
}
.padding(.horizontal, .layoutPadding)
}
.safeAreaInset(edge: .bottom) {
MessageInputBar()
}
.onAppear {
scrollProxy = proxy
withAnimation {
proxy.scrollTo(Constants.bottomAnchor, anchor: .bottom)
}
}
}
}
}
Example: horizontal chips
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 8) {
ForEach(chips) { chip in
ChipView(chip: chip)
}
}
}
Example: adaptive grid
let columns = [GridItem(.adaptive(minimum: 120))]
ScrollView {
LazyVGrid(columns: columns, spacing: 8) {
ForEach(items) { item in
GridItemView(item: item)
}
}
.padding(8)
}
Design choices to keep
- Use
Lazy*stacks when item counts are large or unknown. - Use non-lazy stacks for small, fixed-size content to avoid lazy overhead.
- Keep IDs stable when using
ScrollViewReader. - Prefer explicit animations (
withAnimation) when scrolling to an ID.
Pitfalls
- Avoid nesting scroll views of the same axis; it causes gesture conflicts.
- Don’t combine
ListandScrollViewin the same hierarchy without a clear reason. - Overuse of
LazyVStackfor tiny content can add unnecessary complexity.