Create a Stunning Panoramic Carousel View in SwiftUI (Like SCRL App)
A Panoramic Carousel View is an immersive way to showcase images, allowing users to scroll, zoom, drag, and interact with content seamlessly. Inspired by the SCRL app, we’ll build a custom panoramic carousel in SwiftUI with smooth transitions and a stunning UX.
🚀 Features We’ll Cover:
✅ Smooth horizontal scrolling
✅ Zoom & pinch gestures for interaction
✅ Drag & pan functionality
✅ Infinite scrolling effect
✅ Image selection & dynamic content addition
1️⃣ Creating the Panoramic Carousel Layout
Start by setting up a scrollable horizontal carousel in SwiftUI:
import SwiftUI
struct PanoramicCarouselView: View {
let images: [String] = ["image1", "image2", "image3", "image4"]
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 10) {
ForEach(images, id: \ .self) { image in
Image(image)
.resizable()
.scaledToFit()
.frame(height: 300)
.cornerRadius(15)
.shadow(radius: 5)
}
}
.padding()
}
}
}
🔹 Key Elements:
- ScrollView(.horizontal) enables seamless scrolling.
- HStack arranges images side by side.
- cornerRadius & shadow for a polished design.
2️⃣ Adding Zoom & Pinch Gesture Support
Allow users to pinch to zoom images for better interaction:
struct ZoomableImageView: View {
let image: String
@State private var scale: CGFloat = 1.0
var body: some View {
Image(image)
.resizable()
.scaledToFit()
.frame(height: 300)
.cornerRadius(15)
.shadow(radius: 5)
.scaleEffect(scale)
.gesture(
MagnificationGesture()
.onChanged { value in
scale = value.magnitude
}
.onEnded { _ in
withAnimation {
scale = 1.0 // Reset after zoom
}
}
)
}
}
🔹 How It Works:
- MagnificationGesture() detects pinch zoom.
- scaleEffect() applies zoom dynamically.
- onEnded resets zoom with animation.
3️⃣ Enabling Drag & Pan Gestures
Enhance user experience with drag gestures:
struct DraggableCarouselItem: View {
let image: String
@State private var offset: CGSize = .zero
var body: some View {
Image(image)
.resizable()
.scaledToFit()
.frame(height: 300)
.cornerRadius(15)
.shadow(radius: 5)
.offset(offset)
.gesture(
DragGesture()
.onChanged { value in
offset = value.translation
}
.onEnded { _ in
withAnimation {
offset = .zero // Reset position
}
}
)
}
}
🔹 Drag Gesture Mechanics:
- DragGesture() enables smooth panning.
- offset() moves the image dynamically.
- Animation resets position after release.
4️⃣ Implementing Infinite Scrolling Effect
To create an infinite scrolling experience, use a GeometryReader:
struct InfiniteScrollView: View {
let images: [String] = ["image1", "image2", "image3", "image4"]
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 10) {
ForEach(Array(images.enumerated()), id: \ .offset) { index, image in
Image(image)
.resizable()
.scaledToFit()
.frame(height: 300)
.cornerRadius(15)
.shadow(radius: 5)
.id(index) // Ensures smooth transition
}
}
.padding()
}
}
}
🔹 Performance Boost:
- LazyHStack loads images efficiently.
- id(index) ensures a smooth transition between images.
5️⃣ Adding New Images Dynamically
Allow users to add new images dynamically:
struct DynamicImageCarousel: View {
@State private var images: [String] = ["image1", "image2"]
var body: some View {
VStack {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 10) {
ForEach(images, id: \ .self) { image in
Image(image)
.resizable()
.scaledToFit()
.frame(height: 300)
.cornerRadius(15)
.shadow(radius: 5)
}
}
.padding()
}
Button("Add New Image") {
images.append("newImage")
}
.padding()
}
}
}
🔹 How It Works:
- @State manages the dynamic image list.
- Button action appends a new image.
🎯 Wrapping Up
We’ve built a feature-rich Panoramic Carousel with:
✅ Horizontal scrolling for seamless browsing
✅ Pinch to zoom for enhanced viewing
✅ Drag gestures for natural interaction
✅ Infinite scrolling for an immersive experience
✅ Dynamic image addition for flexibility
🚀 What’s Next? Try adding:
- Page indicators & animations
- Parallax effects for a richer feel
- Integration with a backend image API
Comments
Post a Comment