Spatial SwiftUI: Using Look to Scroll
We can let users look to scroll with the Scroll Input Behavior modifier.
Overview
visionOS 26 includes a new feature called Look to Scroll. Users can look near the edge of a view to scroll its content. We can opt our views into this feature by using the new scrollInputBehavior.
ScrollView(.vertical, showsIndicators: false) {
...
}
.scrollInputBehavior(.enabled, for: .look)behavior: automatic, enabled, disabledinput:.lookor.look(axes:)
This feature is mostly useful on non-interactive content such as text and images. I would avoid using this on forms or complex interfaces.
Example Code
We have three examples:
- Vertical only
- Horizontal only
- Vertical and Horizontal with options to select active axes
struct Example100: View {
@State private var inputKind: ScrollInputKind = .look
var body: some View {
TabView {
// MARK: - Vertical list
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .center, spacing: 16) {
ForEach(0..<101, id: \.self) { number in
Text("\(number)")
.font(.extraLargeTitle2)
.padding()
.frame(width: 120, height: 80)
.background(Color(.stepGreen))
.cornerRadius(16)
}
}
.padding()
}
.scrollInputBehavior(.enabled, for: .look)
.tabItem {
Label("Vertical", systemImage: "chevron.up.chevron.down")
}
// MARK: - Horizontal row
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 16) {
ForEach(0..<101, id: \.self) { number in
Text("\(number)")
.font(.extraLargeTitle2)
.padding()
.frame(width: 120, height: 80)
.background(Color(.stepGreen))
.cornerRadius(16)
}
}
.padding()
}
.scrollInputBehavior(.enabled, for: .look)
.tabItem {
Label("Horizontal", systemImage: "chevron.left.chevron.right")
}
// MARK: - Scrollable grid (both axes)
ScrollView([.horizontal, .vertical], showsIndicators: false) {
let columns = Array(repeating: GridItem(.flexible(), spacing: 16), count: 12)
LazyVGrid(columns: columns, spacing: 16) {
ForEach(0..<101, id: \.self) { number in
Text("\(number)")
.font(.extraLargeTitle2)
.padding()
.frame(width: 120, height: 80)
.background(Color(.stepGreen))
.cornerRadius(16)
}
}
.padding()
}
.background(.thickMaterial)
.scrollInputBehavior(.enabled, for: inputKind)
.ornament(attachmentAnchor: .scene(.top), contentAlignment: .bottom, ornament: {
let display = inputKind == .look ? "All" : inputKind == .look(axes: .horizontal) ? "Horizontal" : "Vertical"
Text("\(display)")
.padding()
.glassBackgroundEffect()
})
.ornament(attachmentAnchor: .scene(.trailing), contentAlignment: .leading, ornament: {
VStack {
Button(action: {
inputKind = .look
}, label: {
Image(systemName: "arrow.up.and.down.and.arrow.left.and.right")
})
Button(action: {
inputKind = .look(axes: .vertical)
}, label: {
Image(systemName: "chevron.up.chevron.down")
})
Button(action: {
inputKind = .look(axes: .horizontal)
}, label: {
Image(systemName: "chevron.left.chevron.right")
})
}
.padding()
.glassBackgroundEffect()
})
.tabItem {
Label("Grid", systemImage: "square.grid.3x3")
}
}
}
}Support our work so we can continue to bring you new examples and articles.

Follow Step Into Vision