Skip to content
TStrawberryPublic

About

Horizontal Carousel for SwiftUI

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Carousel

A SwiftUI package that builds a horizontally scrolling, infinitely looping carousel with variable-width slides, snap-to-item scrolling, scroll visibility reporting, and optional auto-advance.

Features

  • Infinite horizontal scrolling — Seamlessly scroll in both directions without limits.
  • Flexible slide sizing — Supports slides with varying widths and heights, with customizable vertical alignment.
  • Snap-to-item scrolling — Easily snaps to the nearest slide when scrolling.
  • Visibility reporting — Get notified about each slide’s visibility and position as you scroll.
  • Auto-advance — Optionally scrolls to the next slide automatically on a set interval, with smart pause during user interaction.
  • Performance optimized — Ensures smooth scrolling, even with complex layouts or large content.

Requirements

Platform Minimum version
iOS 18.0
tvOS 18.0
watchOS 11.0
macOS 26.0

Installation

Add the following line to your dependencies in the Package.swift file:

.package(url: "https://github.com/TStrawberry/Carousel.git", from: "v1.0.0")

Usage

Import the module and wrap your slides in Carousel:

import SwiftUI
import Carousel

struct ExampleView: View {
    var body: some View {
        Carousel(alignment: .center, spacing: 10) {
            ForEach(0..<10, id: \.self) { index in
                SlideView(index: index)
                    .containerRelativeFrame(.horizontal) { width, _ in
                        width * (index.isMultiple(of: 2) ? 1 : 0.5)
                    }
                    .id(index)
                    .onCarouselScrollVisibilityChange { visibility in
                        // visibility.isVisible, visibility.visiblePercentage
                    }
            }
        }
    }
}

Vertical alignment and spacing

Carousel(alignment: .bottom, spacing: 16) {
    // slides…
}

Programmatic scrolling

Attach scrollPosition to drive or observe the scroll offset:

@State private var scrollPosition = ScrollPosition()

Carousel { /* … */ }
    .scrollPosition($scrollPosition, anchor: .leading)

// Example: scroll to a slide by id
withAnimation(.smooth) {
    scrollPosition.scrollTo(id: someIndex)
}

Auto-scroll

Carousel { /* … */ }
    .autoScrollCarousel(timeInterval: 3)

By default, auto-scroll moves to the next slide using each item’s layout id. You can customize the action:

.autoScrollCarousel(timeInterval: 3) { scrollPosition, index in
    scrollPosition.wrappedValue.scrollTo(id: index.advanced(by: 1).id)
}

Auto-scroll does not run while the user is actively scrolling.

Visibility

CarouselVisibility exposes:

Property Description
isVisible Whether the slide’s frame intersects the scroll view’s visible rect
visiblePercentage Fraction of the slide’s width that is visible (0…1)
scrollGeometry Current ScrollGeometry from the scroll view
frame The slide’s frame in content coordinates

Attach the modifier to each slide:

.onCarouselScrollVisibilityChange { visibility in
    if visibility.isVisible {
        print("Slide visible: \(visibility.visiblePercentage)")
    }
}

Combine with SwiftUI’s onScrollVisibilityChange if you only need a boolean threshold per slide.

License

MIT © 2026 Tao Tang

About

Horizontal Carousel for SwiftUI

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages