A SwiftUI ScrollView that runs a callback when subviews are scrolled in and out of view.

Related tags

Layout swift swiftui
Overview

VisibilityTrackingScrollView

This package provides a variant of ScrollView that you can use to track whether views inside it are actually visible.

Usage:

    var body: some View {
        VisibilityTrackingScrollView(action: handleVisibilityChanged) {
            LazyVStack {
                ForEach(0..<100, id: \.self) { item in
                    Text("\(item)")
                        .trackVisibility(id: "\(item)")
                }
            }
        }
    }
    
    func handleVisibilityChanged(_ id: String, change: VisibilityChange) {
        switch change {
            case .shown: print("\(id) shown")
            case .hidden: print("\(id) hidden")
        }
    }

Any view that you want to track should have the trackVisibility modifier applied to it.

When a tracked view is scrolled into or out of the visible portion of the container, the callback will be called, with the id and new state of the tracked view.

You can use any hashable type for the identifier that you pass to .trackVisibility, but it must match the type that the callback is using (in the example above, we're using String identifiers).

If you accidentally use a different types in both places, it won't be detected at compile-time, since it's completely valid code. At runtime, however, the trackVisiblity modifier will fail to find the environment object that it is expecting, and you'll get a crash.

Discussion

In an ideal world, this wouldn't be necessary because ScrollView would have some decent support for this kind of thing out-of-the-box.

This particular view came out of a discussion about unnecessary refreshes in SwiftUI and how to avoid them.

A technique like this was being used in an app, but was potentially causing changes to environment objects that also had other purposes, causing more refreshing that was strictly needed.

I suggested trying to isolate this behaviour, and then realised that I could probably actually package it up as a generic view/modifier pair.

It makes heavy use of GeometryReader, which isn't ideal, but realistically is the only way that I know of that works in a timely manner.

Example

See the Extras folder for an example project.

You might also like...
ReadabilityModifier - UIKits readableContentGuide for every SwiftUI View, in the form of a ViewModifier
ReadabilityModifier - UIKits readableContentGuide for every SwiftUI View, in the form of a ViewModifier

ReadabilityModifier UIKits readableContentGuide for every SwiftUI View, in the form of a ViewModifier What it is Displaying multiple lines of text in

Add validations to your text fields, Group them together and navigate through them via keyboard's return button and accessory view.
Add validations to your text fields, Group them together and navigate through them via keyboard's return button and accessory view.

TFManager Let's say you have multiple UITextFields to get data from users. You need to handle each field keyboard's return key and add an accessory vi

LayoutKit is a fast view layout library for iOS, macOS, and tvOS.
LayoutKit is a fast view layout library for iOS, macOS, and tvOS.

🚨 UNMAINTAINED 🚨 This project is no longer used by LinkedIn and is currently unmaintained. LayoutKit is a fast view layout library for iOS, macOS, a

LayoutKit is a fast view layout library for iOS, macOS, and tvOS.
LayoutKit is a fast view layout library for iOS, macOS, and tvOS.

🚨 UNMAINTAINED 🚨 This project is no longer used by LinkedIn and is currently unmaintained. LayoutKit is a fast view layout library for iOS, macOS, a

MyLayout is a simple and easy objective-c framework for iOS view layout
MyLayout is a simple and easy objective-c framework for iOS view layout

MyLayout is a powerful iOS UI framework implemented by Objective-C. It integrates the functions with Android Layout,iOS AutoLayout,SizeClass, HTML CSS float and flexbox and bootstrap. So you can use LinearLayout,RelativeLayout,FrameLayout,TableLayout,FlowLayout,FloatLayout,PathLayout,GridLayout,LayoutSizeClass to build your App 自动布局 UIView UITableView UICollectionView RTL

Boardy - Boardy serves as a digital bulletin board on iOS platforms built for high schoolers to share and view information from others in a convenient manner.

Boardy Boardy serves as a lightweight digital bulletin board on iOS platforms built for high schoolers to share and view information from others in a

LoadingButtton - Add button extendded from LoadingButton in the view and make it center horizontally
LoadingButtton - Add button extendded from LoadingButton in the view and make it center horizontally

LoadingButtton Usage/Examples Add button extendded from LoadingButton in the vie

SwiftLayout - View hierarchy and autolayout DSL library

SwiftLayout view hierarchy and autolayout DSL library goal 뷰의 계층구조와 constraint 관

What's New In SwiftUI for iOS 16 - Xcode 14 -  SwiftUI 4.0
What's New In SwiftUI for iOS 16 - Xcode 14 - SwiftUI 4.0

SwiftUI4 What's New In SwiftUI for iOS 16 - Xcode 14 - SwiftUI 4.0 (Work in progress....) Swift Charts Presentation Detents(Half Sheet & Small Sheets)

Releases(v1.0.3)
Owner
Elegant Chaos
Mac and iOS software development, consultancy, debugging, and contracting. Applications, games, multimedia.
Elegant Chaos
✂ Easy to use and flexible library for manually laying out views and layers for iOS and tvOS. Supports AsyncDisplayKit.

ManualLayout Table of Contents Installation Usage API Cheat Sheet Installation Carthage Add the following line to your Cartfile. github "isair/ManualL

Baris Sencan 280 Sep 29, 2022
Modern-collection-view - Modern collection view for swift

Modern collection view Sample application demonstrating the use of collection vi

Nitanta Adhikari 1 Jan 24, 2022
Horizontal and Vertical collection view for infinite scrolling that was designed to be used in SwiftUI

InfiniteScroller Example struct ContentView: View { @State var selected: Int = 1 var body: some View { InfiniteScroller(direction: .ve

Serhii Reznichenko 5 Apr 17, 2022
A SwiftUI proof-of-concept, and some sleight-of-hand, which adds rain to a view's background

Atmos A SwiftUI proof-of-concept, and some sleight-of-hand, which adds rain to a view's background. "Ima use this in my app..." Introducing Metal to S

Nate de Jager 208 Jan 2, 2023
Flow layout / tag cloud / collection view in SwiftUI.

SwiftUIFlowLayout A Flow Layout is a container that orders its views sequentially, breaking into a new "line" according to the available width of the

Gordan Glavaš 115 Dec 28, 2022
NStack is a SwiftUI view that allows you to hoist navigation state into a Coordinator

An NStack allows you to manage SwiftUI navigation state with a single stack property. This makes it easy to hoist that state into a high-level view, such as a coordinator. The coordinator pattern allows you to write isolated views that have zero knowledge of their context within the navigation flow of an app.

John Patrick Morgan 469 Dec 27, 2022
Half modal view for SwiftUI

ResizableSheet ResizableSheeet is a half modal view library for SwiftUI. You can easily implement a half modal view. Target Swift5.5 iOS14+ Installati

matsuji 76 Dec 16, 2022
✨ Super sweet syntactic sugar for SwiftUI.View initializers.

ViewCondition ✨ Super sweet syntactic sugar for SwiftUI.View initializers. At a Glance struct BorderTextView: View { var color: Color? @ViewBuild

Yoon Joonghyun 76 Dec 17, 2022
SwiftUI package to present a Bottom Sheet interactable view with the desired Detents. Also known as Half sheet.

BottomSheetSUI BottomSheetSUI is a package that gives you the ability to show a Bottom sheet intractable, where you can add your own SwiftUI view. You

Aitor Pagán 8 Nov 28, 2022
A grid layout view for SwiftUI

Update July 2020 - latest SwiftUI now has built-in components to do this, which should be used instead. FlowStack FlowStack is a SwiftUI component for

John Susek 147 Nov 10, 2022