Created
September 7, 2026 21:12
-
-
Save lanserxt/6232047ea070ce68edd03075a374a546 to your computer and use it in GitHub Desktop.
visionOS 27: UILookToScrollInteraction example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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