Skip to content

Instantly share code, notes, and snippets.

@lanserxt
Created September 7, 2026 21:12
Show Gist options
  • Select an option

  • Save lanserxt/6232047ea070ce68edd03075a374a546 to your computer and use it in GitHub Desktop.

Select an option

Save lanserxt/6232047ea070ce68edd03075a374a546 to your computer and use it in GitHub Desktop.
visionOS 27: UILookToScrollInteraction example
import UIKit
// Look to Scroll is a visionOS feature exposed through UIKit.
@available(visionOS 27.0, *)
final class ReaderViewController: UIViewController {
private let scrollView = UIScrollView()
private let contentLabel = UILabel()
private let controlsView = UIVisualEffectView(
effect: UIBlurEffect(style: .systemMaterial)
)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.lookToScrollAxes = .vertical
view.addSubview(scrollView)
contentLabel.translatesAutoresizingMaskIntoConstraints = false
contentLabel.numberOfLines = 0
contentLabel.font = .preferredFont(forTextStyle: .body)
contentLabel.adjustsFontForContentSizeCategory = true
contentLabel.text = Array(
repeating: """
Look to Scroll is designed for large, meaningful content such as articles, notes, messages, and browsing surfaces. The system can scroll the view when the user looks near its scrolling boundary.
""",
count: 18
).joined()
scrollView.addSubview(contentLabel)
controlsView.translatesAutoresizingMaskIntoConstraints = false
controlsView.layer.cornerRadius = 18
controlsView.clipsToBounds = true
let button = UIButton(
configuration: .filled(),
primaryAction: UIAction(
title: "Bookmark",
image: UIImage(systemName: "bookmark")
) { _ in
print("Bookmarked")
}
)
button.translatesAutoresizingMaskIntoConstraints = false
controlsView.contentView.addSubview(button)
NSLayoutConstraint.activate([
button.leadingAnchor.constraint(equalTo: controlsView.contentView.leadingAnchor, constant: 12),
button.trailingAnchor.constraint(equalTo: controlsView.contentView.trailingAnchor, constant: -12),
button.topAnchor.constraint(equalTo: controlsView.contentView.topAnchor, constant: 12),
button.bottomAnchor.constraint(equalTo: controlsView.contentView.bottomAnchor, constant: -12)
])
controlsView.addInteraction(
UILookToScrollInteraction.exclusionRegion()
)
view.addSubview(controlsView)
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
contentLabel.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 24),
contentLabel.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -24),
contentLabel.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 24),
contentLabel.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -80),
contentLabel.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor, constant: -48),
controlsView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
controlsView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16)
])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment