Search code examples
iosanimationscrollviewswiftuioffset

How do you make an element in a SwiftUI loop full screen? Like Apple's, App of the day


Here's a gif of what I currently have

Trying a bunch of things here, like offset and zIndex but they don't change the position, I'm looking for something like absolute position in css to make the card full screen.

    var body: some View {
    VStack {
        Text("")
    }
    .frame(minWidth: 0, maxWidth: .infinity)
    .frame(height: show ? UIScreen.main.bounds.height : 200)
    .zIndex(show ? 1 : 0)
    .background(/*@START_MENU_TOKEN@*/Color.blue/*@END_MENU_TOKEN@*/)
    .cornerRadius(show ? 0 : 20)
    .padding(show ? 0 : 30)
    .offset(y: show ? 0 : viewState.height)
    .animation(.easeInOut(duration: 0.3))
}

Solution

  • You may want to use GeometryReader instead, combining with edgesIgnoringSafeArea like this:

    struct ContentView: View {
    
        @State var show = false
    
        var body: some View {
            GeometryReader { geo in
                VStack { Text("") }
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .frame(height: self.show ? geo.size.height : 200)
                    .background(/*@START_MENU_TOKEN@*/Color.blue/*@END_MENU_TOKEN@*/)
                    .cornerRadius(self.show ? 0 : 20)
                    .padding(self.show ? 0 : 30)
                    .offset(y: self.show ? 0 : 0)
                    .animation(.easeInOut(duration: 0.3))
                    .onTapGesture {
                        self.show.toggle()
                }
            }.edgesIgnoringSafeArea(.all)
        }
    }
    

    Output:

    Single View[1


    Note That This was just an answer to the original question and original provided code, If you like to embed the card in another way like using ScrollView, you should consider some changes to the original code of course. For example:

    struct CardView: View {
        @Binding var show: Bool
    
        var body: some View {
    
            Rectangle()
                .foregroundColor(.blue)
                .cornerRadius(self.show ? 0 : 20)
                .padding(self.show ? 0 : 30)
                .animation(.easeInOut(duration: 0.3))
        }
    }
    
    extension Int: Identifiable { public var id: Int { self } }
    
    struct ContentView: View {
    
        @State var show = false
    
        var body: some View {
            GeometryReader { geo in
                ScrollView {
                    VStack {
                        ForEach(0..<1) { item in
                            CardView(show: self.$show)
                                .frame(height: self.show ? geo.size.height : 200)
                            .onTapGesture { self.show.toggle() }
    
    
                        }
                    }
                }
            }.edgesIgnoringSafeArea(.all)
        }
    }
    

    Inside a scrollView