fatbobman / Infinite4Pager

Infinite4Pager is a flexible and powerful SwiftUI component that provides infinite scrolling capabilities in four directions: up, down, left, and right. It's perfect for creating image galleries, card decks, or any other content that requires seamless navigation in multiple directions.
MIT License
103 stars 2 forks source link
swiftui swiftui-components

Infinite4Pager

Infinite4Pager is a flexible and powerful SwiftUI component that provides infinite scrolling capabilities in four directions: up, down, left, and right. It's perfect for creating image galleries, card decks, or any other content that requires seamless navigation in multiple directions.

Please read Developing an Infinite Four-Direction Scrollable Pager with SwiftUI to understand the implementation principles of this library and for more usage notes.

https://github.com/fatbobman/Infinite4Pager/assets/55673881/e98bd549-e639-46e7-9adf-b9e82b75b858

Features

Requirements

Installation

Swift Package Manager

You can add Infinite4Pager to your project using Swift Package Manager. In Xcode, go to File > Swift Packages > Add Package Dependency and enter the repository URL:

https://github.com/fatbobman/Infinite4Pager.git

Usage

Here's a basic example of how to use Infinite4Pager:

import SwiftUI
import Infinite4Pager

struct TestView: View {
  var body: some View {
    Infinite4Pager(
      initialHorizontalPage: 2,
      initialVerticalPage: 2,
      totalHorizontalPage: 5,
      totalVerticalPage: 5,
      enableClipped: false,
      enablePageVisibility: true,
      getPage: { h, v in
        PageView(h: h, v: v)
      }
    )
    .ignoresSafeArea()
  }
}

struct PageView: View {
  let h: Int
  let v: Int
  let images = ["img1", "img2", "img3", "img4", "img5"]
  @Environment(\.pagerCurrentPage) var mainPage
  @State var percent: Double = 0
  @State var isCurrent = false
  var body: some View {
    VStack {
      let index = abs((h + v) % (images.count - 1))
      Color.clear
        .overlay(
          Image(images[index])
            .resizable()
            .aspectRatio(contentMode: .fill)
            .overlay(
              VStack {
                Text("\(h),\(v)")
                Text("visibility \(percent)")
                Text("isCurrent:\(isCurrent)")
              }
              .font(.largeTitle)
              .foregroundStyle(.white)
              .padding()
              .background(
                RoundedRectangle(cornerRadius: 15)
                  .foregroundColor(.black)
              )
            )
        )
        .onPageVisible { percent in
          if let percent {
            self.percent = percent
          }
        }
        .task(id: mainPage) {
          if let mainPage {
            if mainPage.horizontal == h, mainPage.vertical == v {
              isCurrent = true
            }
          }
        }
        .clipped()
    }
  }
}

For more advanced usage and customization options, please refer to the documentation.

Customization

Infinite4Pager offers several customization options:

Page Visibility and Data Management

A view modifier similar to onScrollVisibilityChange that provides the view with the current proportion of the visible area.

  PageView()
   .onPageVisible { percent in
    if percent > 0.1 {
      // play video
    }
  }

The environment value pagerCurrentPage provides information about the current view within the container.

.task(id: mainPage) {
  if let mainPage {
    if mainPage.horizontal == h, mainPage.vertical == v {
      // load data , enable animation
    }
  }
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

Infinite4Pager is available under the MIT license. See the LICENSE file for more info.