A liberated _ScrollView and _PagingView of SwiftUI.

Overview

SolidScroll

A liberated _ScrollView and _PagingView of SwiftUI.

Overview

SolidScroll allows to unlock the potential of the scroll view in SwiftUI.

Unlike the regular SwiftUI ScrollView and ScrollViewProxy, the hidden SwiftUI _ScrollView and _ScrollViewProxy types allow to get near-UIScrollView control over the status of scrolling in real time, content insets, animate content offset, and much more.

SolidScroll is a set of type aliases to SwiftUI hidden types, and couple of helper initializers for the convinience.

Also, the library contains docc-compatible documentation where each type alias is represented with the hidden interface of the aliased type.

Advanced scroll view use-cases

SwiftUI has a hidden _ContainedScrollViewKey type, which is actually a not-publicly-conformed PreferenceKey type. This preference reports the _ScrollViewProxy where all functionality of the _ScrollView is unlocked. In order to get the proxy, simply create SolidScrollView in the body of your view, then store the proxy in a @State, as shown in the following example:

import SolidScroll

struct ContentView: View {
  var config = ScrollViewConfig()
  @State var scrollViewProxy: SolidScrollViewProxy?

  var body: some View {
    VStack(spacing: 0) {
      SolidScrollView(config) {
        VStack(spacing: 0) {
          Color.red.frame(height: 200)
          Color.green.frame(height: 200)
          Color.blue.frame(height: 200)
          Color.black.frame(height: 200)
        }
      }
      Button("Scroll to 3/4 of the content height via proxy") {
        guard let scrollViewProxy = scrollViewProxy else { return }
        let contentOffset = CGPoint(x: 0, y: min(scrollViewProxy.contentSize.height * 3.0 / 4, scrollViewProxy.maxContentOffset.y))
        scrollViewProxy.setContentOffset(contentOffset, animated: true, completion: { completed in
          print("Scrolled via proxy to \(contentOffset)! Completed: \(completed)")
        })
      }
    }
    .onPreferenceChange(ContainedScrollViewKey.self) {
      scrollViewProxy = $0
    }
  }
}

Advanced scroll view use-cases with paging

For paging, SwiftUI has a different hidden type called _PagingView. It's a wrapper on scroll view that supports paging. The direction of the scrolling and the size of the page in the scrolling direction is controlled by _PagingViewConfig. All pages take the same size. If size is nil, page takes the full available width or height on the screen (in correspondance with the scroll direction). It's useful for implementation of custom tab bar, image carousel or other pagination behavior. The usage example is shown below.

import SolidScroll

struct PagingContentView: View {
  @State var currentPage: Int = 0
  let config: PagingViewConfig

  init() {
    var config = PagingViewConfig()
    config.direction = .horizontal
    config.size = 100
    config.margin = 0
    config.spacing = 0
    self.config = config
  }

  var body: some View {
    PagingView(config: config, page: $currentPage, views: Array(0...10).map { page(at: $0) })
  }

  @ViewBuilder
  func page(at index: Int) -> some View {
    Text("Page \(index)")
      .frame(maxWidth: .infinity, maxHeight: .infinity)
      .background(backgroundColor(at: index))
  }

  func backgroundColor(at index: Int) -> Color {
    let indexMod = (index % 3)
    switch indexMod {
    case 0: return Color.red
    case 1: return Color.green
    case 2: return Color.blue
    default: return Color.clear
    }
  }
}

Demo of the library

SolidScroll Demo on YouTube

Installation

Xcode 13

  1. Select your project in File Navigator, then select the project again on top of the list of targets. You'll see list of packages.
  2. Press + button.
  3. In the appeared window, press + button in the bottom left corner.
  4. In the appeared menu, select "Add Swift Package Collection"
  5. In the appeared dialog, enter package collection URL: https://swiftpackageindex.com/edudnyk/collection.json
  6. Press "Add Collection"
  7. Select SolidScroll package from the collection.

If you want to use SolidScroll in any other project that uses SwiftPM, add the package as a dependency in Package.swift:

dependencies: [
  .package(name: "SolidScroll", url: "https://github.com/edudnyk/SolidScroll.git", from: "0.0.1"),
]

Next, add SolidScroll as a dependency of your test target:

targets: [
  .target(name: "MyApp", dependencies: ["SolidScroll"], path: "Sources"),
]

Carthage

If you use Carthage, you can add the following dependency to your Cartfile:

github "edudnyk/SolidScroll" ~> 0.0.1

CocoaPods

If your project uses CocoaPods, add the pod to any applicable targets in your Podfile:

target 'MyApp' do
  pod 'SolidScroll', '~> 0.0.1'
end
You might also like...
A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI.
A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI.

BetterSafariView A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI. Contents Motivation Requirements U

A SwiftUI Library for creating resizable partitions for View Content.
A SwiftUI Library for creating resizable partitions for View Content.

Partition Kit Recently Featured In Top 10 Trending Android and iOS Libraries in October and in 5 iOS libraries to enhance your app! What is PartitionK

A micro UIStackView convenience API inspired by SwiftUI
A micro UIStackView convenience API inspired by SwiftUI

Stacks A micro UIStackView convenience API inspired by SwiftUI. let stack: UIView = .hStack(alignment: .center, margins: .all(16), [ .vStack(spaci

SwiftUI: Components Library Inspired by Twitter's Bootstrap
SwiftUI: Components Library Inspired by Twitter's Bootstrap

bootswiftui SwiftUI: Components Library Inspired by Twitter's Bootstrap Warning This is just SwiftUI exercise. Please do not consider using this repo

Zeplin component preview for your SwiftUI views
Zeplin component preview for your SwiftUI views

A Zeplin component preview for your SwiftUI views. You can use Zeplin components instead of real views within your app until you implement them.

A SwiftUI Views for wrapping HStack elements into multiple lines
A SwiftUI Views for wrapping HStack elements into multiple lines

SwiftUI WrappingStack A SwiftUI Views for wrapping HStack elements into multiple lines. List of supported views WrappingHStack - provides HStack that

Create SwiftUI Views with any data

Create SwiftUI Views with any data

Advanced List View for SwiftUI with pagination & different states

AdvancedList This package provides a wrapper view around the SwiftUI List view which adds pagination (through my ListPagination package) and an empty,

Swipe Left2Right & Right2Left, pure SwiftUI implementation
Swipe Left2Right & Right2Left, pure SwiftUI implementation

SwipeCell Preview Features Swipe cell from Left2Right & Right2Left. Destructive swipe Usage Simply add onSwipe(leading, trailing) method to your list

Comments
  • How to use LazyVStack in SolidScrollView?

    How to use LazyVStack in SolidScrollView?

    struct ContentView: View { var body: some View { SolidScrollView(.vertical, showsIndicators: false) { LazyVStack { ForEach(0 ..< 50, id: \.self) { _ in Color.blue .frame(height: 44) } } } } }

    opened by K999999999 0
  • The demo segfaults on iOS 15

    The demo segfaults on iOS 15

    Hi,
    I was checking SolidScroll out to, but unfortunately, when running on Xcode 13.2 and iOS 15.2, it crashed when I ran the demo in the simulator. Is this way unsupported in iOS 15?

    opened by niklassaers 0
Owner
Eugene Dudnyk
Eugene Dudnyk
SwiftUI-Drawer - A bottom-up drawer in swiftUI

SwiftUI-Drawer A bottom-up drawer view. Contents Installation Examples Installat

Bruno Wide 9 Dec 29, 2022
SwiftUI-Margin adds a margin() viewModifier to a SwiftUI view.

SwiftUI-Margin adds a margin() viewModifier to a SwiftUI view. You will be able to layout the margins in a CSS/Flutter-like.

Masaaki Kakimoto(柿本匡章) 2 Jul 14, 2022
Blobmorphism is a brand new design language I've created to break free of the material overload in iOS, built in SwiftUI. Everything feels smooth and fluid.

Blobmorphism is a brand new design language I've created to break free of the material overload in iOS, built in SwiftUI. Everything feels smooth and fluid.

Ethan Lipnik 89 Nov 29, 2022
SwiftUI view enabling navigation between pages of content, imitating the behaviour of UIPageViewController for iOS and watchOS

PageView SwiftUI view enabling page-based navigation, imitating the behaviour of UIPageViewController in iOS. Why SwiftUI doesn't have any kind of pag

Kacper Rączy 365 Dec 29, 2022
A set of UIKit helpers that simplify the usage of UIKit view's and controller's in SwiftUI.

A set of UIKit helpers that simplify the usage of UIKit view's and controller's in SwiftUI. Many of these helpers are useful even in a pure UIKit project.

SwiftUI+ 6 Oct 28, 2022
The Bloc Pattern is a way to separate UI and Logic in SwiftUI codes;

The Bloc Pattern is a way to separate UI and Logic in SwiftUI codes. The Bloc is like a state machine where it accepts an event and produce a state.

mehdi sohrabi 3 Apr 20, 2022
Runtime introspection and unit testing of SwiftUI views

ViewInspector is a library for unit testing SwiftUI views. It allows for traversing a view hierarchy at runtime providing direct access to the underlying View structs.

Alexey Naumov 1.5k Jan 2, 2023
A few drop-in SwiftUI components for easily importing and thumb-nailing files

FilesUI A few drop-in SwiftUI components for easily importing and thumb-nailing files Usage 1. Import Files To import files you can use the FileImport

Brianna Zamora 3 Oct 19, 2022
SwiftUI components and extensions that seem to be highly reusable

SwiftUI components and extensions that seem to be highly reusable

Yusuke Hosonuma 56 Dec 15, 2022
A number of preset loading indicators created with SwiftUI

ActivityIndicatorView A number of preset loading indicators created with SwiftUI We are a development agency building phenomenal apps. Usage Create an

Exyte 956 Dec 26, 2022