Parallax Effect in SwiftUI

DevTechie Inc
Jun 24, 2022


Photo by Anna Mircea on Unsplash

In this article, we will build parallax effect using GeometryReader. Here is what our end product will look like:

We will start with an array containing some sample data:

var devTechieCourses = [
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3"
    ]
Next we will create a VStack, Text and ScrollView.

struct ParallaxEffect: View {
    var devTechieCourses = [
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3"
    ]
    var body: some View {
        VStack {
            Text("DevTechie Courses")
                .font(.largeTitle)
            
            ScrollView {
            
            }.ignoresSafeArea(edges: .vertical)
        }
    }
}
ScrollView will host a ZStack which will have a GeometryReader and another VStack. We will add our background image in GeometryReader and make it resizable. This image will be set to fill the screen and we will use offset modifier to offset on y axis as shown below

struct ParallaxEffect: View {
    var devTechieCourses = [
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3"
    ]
    var body: some View {
        VStack {
            Text("DevTechie Courses")
                .font(.largeTitle)
            
            ScrollView {
                ZStack {
                    GeometryReader { geo in
                        Image("imageSample")
                            .resizable()
                            .scaledToFill()
                            .offset(y: -geo.frame(in: .global).origin.y / 2)
                    }
                    
                    VStack(alignment: .leading, spacing: 40) {}
                    .padding(.top, 100)
                }
            }.ignoresSafeArea(edges: .vertical)
        }
    }
}
Now we will add ForEach inside our VStack and render all the cells:

struct ParallaxEffect: View {
    var devTechieCourses = [
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3",
        "Mastering SwiftUI 3",
        "Machine Learning in iOS",
        "Goals app in SwiftUI",
        "E-Commerce App in SwiftUI 3"
    ]
    var body: some View {
        VStack {
            Text("DevTechie Courses")
                .font(.largeTitle)
            
            ScrollView {
                ZStack {
                    GeometryReader { geo in
                        Image("imageSample")
                            .resizable()
                            .scaledToFill()
                            .offset(y: -geo.frame(in: .global).origin.y / 2)
                    }
                    
                    VStack(alignment: .leading, spacing: 40) {
                        ForEach(devTechieCourses, id: \.self) { course in
                            Text(course)
                                .font(.largeTitle)
                                .foregroundColor(.white)
                                
                                .padding()
                                .background(
                                    RoundedRectangle(cornerRadius: 25).frame(height: 100).opacity(0.5)
                                )
                        }
                    }
                    .padding(.top, 100)
                }
            }.ignoresSafeArea(edges: .vertical)
        }
    }
}
And that will give us, our final effect:


With that we have reached the end of this article. Thank you once again for reading. Subscribe to our weekly newsletter at https://www.devtechie.com