Carousel View In SwiftUI

Mobile Apps Academy
3 min readOct 23, 2023

In this article, We will explore how to implement a Carousal View using SwiftUI

Before proceeding, please consider subscribing to our YOUTUBE CHANNEL

It gives us a lot of motivation to produce high-quality content for you guys.

if you are interested in watching the video tutorial, Check out below.

Let's create a SwiftUI file and name it as CarouselView.


import SwiftUI

struct CarouselView: View {

var body: some View {
ZStack {

}
}
}

We need to store the values of dragged and snapped items also xDistance.

import SwiftUI

struct CarouselView: View {
var xDistance: Int = 150

@State private var snappedItem = 0.0
@State private var draggingItem = 0.0
@State var activeIndex: Int = 0

var body: some View {
ZStack {

}
}
}

We need to have child views to contain the views we need inside the carousel view.

Create a SwiftUI file and name it CarouselChildView, with View also extending it to Identifiable.

import SwiftUI

struct CarouselChildView: View, Identifiable {
var id: Int
@ViewBuilder var content : any View

var body: some View {
ZStack {
AnyView(content)
}
}
}

var placeholderCarouselChildViews: [CarouselChildView] = [
CarouselChildView(id: 1) {
ZStack {
RoundedRectangle(cornerRadius: 18)
.fill(Color.red)
Text("1")
.padding()
}
.frame(width: 200, height: 400)

},
CarouselChildView(id: 2) {
ZStack {
RoundedRectangle(cornerRadius: 18)
.fill(Color.gray)
Text("2")
.padding()
}
.frame(width: 200, height: 400)

}
,
CarouselChildView(id: 3) {
ZStack {
RoundedRectangle(cornerRadius: 18)
.fill(Color.cyan)
Text("3")
.padding()
}
.frame(width: 200, height: 400)
}
]

Loop through the views and populate.

import SwiftUI

struct CarouselView: View {
var xDistance: Int = 150

@State private var snappedItem = 0.0
@State private var draggingItem = 0.0
@State var activeIndex: Int = 0

var views : [CarouselChildView] = placeholderCarouselChildViews

var body: some View {
ZStack {
ForEach(views) { item in
item
.scaleEffect(1.0 - abs(distance(item.id)) * 0.2 )
.opacity(1.0 - abs(distance(item.id)) * 0.3 )
.offset(x: offset(item.id), y: 0)
.zIndex(1.0 - abs(distance(item.id)) * 0.1)
}
}
}

func distance(_ item: Int) -> Double {
return (draggingItem - Double(item)).remainder(dividingBy: Double(views.count))
}

func offset(_ item: Int) -> Double {
let angle = Double.pi * 2 / Double(views.count) * distance(item)
return sin(angle) * Double(xDistance)
}
}

Add a DragGesture on ZStack and set the Dragged and Snapped values inside the animation.

import SwiftUI

struct CarouselView: View {
var xDistance: Int = 150

@State private var snappedItem = 0.0
@State private var draggingItem = 0.0
@State var activeIndex: Int = 0

var views : [CarouselChildView] = placeholderCarouselChildViews
var body: some View {
ZStack {
ForEach(views) { item in
item
.scaleEffect(1.0 - abs(distance(item.id)) * 0.2 )
.opacity(1.0 - abs(distance(item.id)) * 0.3 )
.offset(x: offset(item.id), y: 0)
.zIndex(1.0 - abs(distance(item.id)) * 0.1)
}
}
.gesture(
DragGesture()
.onChanged { value in
draggingItem = snappedItem + value.translation.width / 100
}
.onEnded { value in
withAnimation {
draggingItem = snappedItem + value.predictedEndTranslation.width / 100
draggingItem = round(draggingItem).remainder(dividingBy: Double(views.count))
snappedItem = draggingItem
self.activeIndex = views.count + Int(draggingItem)
if self.activeIndex > views.count || Int(draggingItem) >= 0 {
self.activeIndex = Int(draggingItem)
}
}
}
)
}

func distance(_ item: Int) -> Double {
return (draggingItem - Double(item)).remainder(dividingBy: Double(views.count))
}

func offset(_ item: Int) -> Double {
let angle = Double.pi * 2 / Double(views.count) * distance(item)
return sin(angle) * Double(xDistance)
}
}

thats it. Below is the result.

Once again Thanks for stopping by.
Do check out our YOUTUBE CHANNEL

Social Handles

Instagram : https://www.instagram.com/mobileappsacademy/

Twitter : https://twitter.com/MobileAppsAcdmy

LinkedIn : https://www.linkedin.com/company/mobile-apps-academy/

--

--

Mobile Apps Academy

Welcome to Mobile Apps Academy, your go-to channel for all things mobile app development!