A SwiftUI wrapper for Nick Lockwood's iCarousel library with Swift 6 concurrency support
Add iCarousel to your project using Xcode:
- File β Add Package Dependencies
- Enter package URL:
https://github.com/keremersu35/iCarousel-SwiftUI.git- Select version and add to target
Or add to your Package.swift:
dependencies: [
.package(url: "https://github.com/keremersu35/iCarousel-SwiftUI.git", from: "1.0.0")
]import SwiftUI
import iCarouselSwiftUI
struct ContentView: View {
@State private var selectedIndex = 0
let items = ["π", "π", "π", "π", "π"]
var body: some View {
VStack {
Text("Selected: \(items[selectedIndex])")
.font(.title)
CarouselView(items, id: \.self, selection: $selectedIndex) { fruit, index in
Text(fruit)
.font(.system(size: 60))
.frame(width: 120, height: 120)
.background(Circle().fill(Color.blue.opacity(0.3)))
}
.frame(height: 200)
.carouselType(.coverFlow)
.onSelectionChanged { index in
print("Selected: \(index)")
}
}
.padding()
}
}.carouselType(.linear) // Items arranged in a line
.carouselType(.rotary) // Items arranged in a circle
.carouselType(.invertedRotary) // Inverted circular arrangement
.carouselType(.cylinder) // Cylindrical 3D effect
.carouselType(.invertedCylinder) // Inverted cylindrical effect
.carouselType(.wheel) // Ferris wheel style (vertical)
.carouselType(.invertedWheel) // Inverted wheel style
.carouselType(.coverFlow) // Cover Flow style (like iTunes)
.carouselType(.coverFlow2) // Alternative Cover Flow implementation
.carouselType(.timeMachine) // 3D effect like Apple's Time Machine
.carouselType(.invertedTimeMachine) // Inverted Time Machine
.carouselType(.custom) // Custom arrangementCarouselView(items) { item, index in
// Your item view
}
.carouselType(.coverFlow)
.perspective(-1.0/200.0) // 3D perspective effect
.itemSize(width: 200, height: 150) // Fixed item sizes
.spacing(1.2) // Space between items
.bounces(true) // Enable/disable bouncing
.vertical(false) // Horizontal or vertical orientation.tilt(0.9) // 3D tilt angle for CoverFlow/TimeMachine
.radius(150) // Radius for wheel/rotary carousels
.arc(.pi * 1.5) // Arc angle for rotary carousels (in radians)
.perspective(-1.0/400.0) // Custom 3D perspective
.fadeMin(0.2) // Minimum fade distance
.fadeMax(1.0) // Maximum fade distance
.fadeRange(0.8) // Fade range
.fadeMinAlpha(0.3) // Minimum alpha for faded items.wrap(true) // Enable infinite scrolling
.showBackfaces(false) // Show/hide item backfaces when flipped
.offsetMultiplier(1.2) // Scroll sensitivity multiplier
.visibleItems(5) // Maximum visible items (0 = automatic)
.itemCount(10) // Override total item count (0 = use data count)
.autoscroll(1.0) // Automatic scroll speed (0 = disabled).contentOffset(x: 10, y: 0) // Content offset
.viewpointOffset(x: 0, y: 20) // 3D viewpoint offset
.scrollOffset(0.5) // Initial scroll offset.scrollEnabled(true) // Enable/disable scrolling
.pagingEnabled(false) // Enable/disable paging
.scrollSpeed(1.0) // Scroll speed multiplier
.decelerationRate(0.9) // Scroll deceleration rate
.centerWhenSelected(true) // Center item when selected
.stopAtItemBoundary(true) // Stop at item boundaries
.scrollToItemBoundary(true) // Scroll to item boundaries
.ignorePerpendicularSwipes(true) // Ignore perpendicular swipes.onSelectionChanged { index in
Task { @MainActor in
// Update UI on main thread
selectedIndex = index
}
}
.onWillBeginScrolling {
Task { @MainActor in
isScrolling = true
}
}
.onDidEndScrolling {
Task { @MainActor in
isScrolling = false
}
}
.onWillBeginDecelerating {
print("Will begin decelerating")
}
.onDidEndDecelerating {
Task { @MainActor in
isScrolling = false
}
}
.onWillBeginDragging {
print("Will begin dragging")
}
.onDidEndDragging { willDecelerate in
print("Did end dragging, will decelerate: \(willDecelerate)")
}struct CarouselItem: Identifiable, Hashable {
let id = UUID()
let value: String
}
struct CarouselDemo: View {
@State private var currentIndex = 0
@State private var items = [
CarouselItem(value: "A"),
CarouselItem(value: "B"),
CarouselItem(value: "C")
]
var body: some View {
VStack {
CarouselView(items, id: \.id, selection: $currentIndex) { item, index in
Text(item.value)
.frame(width: 100, height: 100)
.background(Color.blue)
}
Button("Add Item") {
items.append(CarouselItem(value: "New"))
}
Button("Go to First") {
currentIndex = 0
}
}
}
}.linear- Items arranged in a line.rotary- Items arranged in a circle (default).invertedRotary- Inverted rotary arrangement.cylinder- Cylindrical 3D effect.invertedCylinder- Inverted cylindrical effect.wheel- Ferris wheel style.invertedWheel- Inverted wheel style.coverFlow- Cover flow style (like iTunes).coverFlow2- Alternative cover flow style.timeMachine- Time machine style.invertedTimeMachine- Inverted time machine style
The project includes comprehensive examples in the SwiftUIWrapper/Examples.swift file.
- iOS 13.0+ / macOS 10.15+ / tvOS 13.0+
- Xcode 15.0+
- Swift 6.0+ (for concurrency support)
- π Documentation: See
SwiftUI/README.mdfor detailed SwiftUI usage - π‘ Examples: Check
SwiftUI/Examples.swiftfor implementation patterns - π Issues: Report bugs on GitHub Issues
- π¬ Discussions: Use GitHub Discussions for questions
Based on Nick Lockwood's original iCarousel library. Modern SwiftUI wrapper with Swift 6 concurrency support.