0

I want when I scroll up the Text ("Hello") will stay fixed, and the text "Welcome " will move up to be on the same line as Text("Hello").

Hope you can give me some solution.Thanks

Design

struct ContentView: View {
    @State var didScrollUp: Bool = false
    @State var Ishstacked: Bool
    var body: some View {
        NavigationView {
            ScrollView {
                ZStack {
                    VStack(alignment:.leading) {
                        VStack {
                           TagLineView(isHStacked: $Ishstacked)
                        }
                        .padding()
                        ZStack(alignment:.leading) {
                            Color(#colorLiteral(red: 0.937254902, green: 0.937254902, blue: 0.937254902, alpha: 1))
                                .edgesIgnoringSafeArea(.all)
                                .cornerRadius(30.0)
                            VStack(alignment: .leading) {
                                Text("Popular")
                                    .font(.custom("PlayfairDisplay-Bold", size: 24))
                                    .padding(.leading,27)
                                    .padding(.top,20)
                                
                                ScrollView (.horizontal, showsIndicators: false) {
                                    HStack (spacing: 0) {
                                        ForEach(0 ..< 4) { i in
                                            ProductCardView(image: Image("chair_\(4-i)"), size: 180)
                                        }
                                        .padding(.leading)
                                    }
                                }
                                .padding(.bottom)
                                
                                Text("Best")
                                    .font(.custom("PlayfairDisplay-Bold", size: 24))
                                    .padding(.horizontal)
                                
                                ScrollView (.horizontal, showsIndicators: false) {
                                    HStack (spacing: 0) {
                                        ForEach(0 ..< 4) { i in
                                            ProductCardView(image: Image("chair_\(4-i)"), size: 180)
                                        }
                                        .padding(.leading)
                                    }
                                }
                                
                                Text("Best")
                                    .font(.custom("PlayfairDisplay-Bold", size: 24))
                                    .padding(.horizontal)
                                
                                ScrollView (.horizontal, showsIndicators: false) {
                                    HStack (spacing: 0) {
                                        ForEach(0 ..< 4) { i in
                                            ProductCardView(image: Image("chair_\(4-i)"), size: 180)
                                        }
                                        .padding(.leading)
                                    }
                                }
                            }
                            
                            
                        }.background(GeometryReader {
                            Color.clear.preference(key: ViewOffsetKey.self,
                                                   value: -$0.frame(in: .named("scroll")).origin.y)
                        })
                        .onPreferenceChange(ViewOffsetKey.self) { didScrollUp = $0 > 5 ? true : false }
                    }
                    
                }
                .coordinateSpace(name: "scroll")
            }
        }
    }
}    

struct TagLineView: View {
        @Binding var isHStacked: Bool
        var body: some View {
            Text("Hello")
                .font(.title)
                .fontWeight(.bold) + Text(isHStacked ? " " : "\n") +  // Adding a newline or adding a space based on the orientation of the stack
                Text("Welcome!")
                .font(.title)
        }
    }
struct ViewOffsetKey: PreferenceKey {
        typealias Value = CGFloat
        static var defaultValue = CGFloat.zero
        static func reduce(value: inout Value, nextValue: () -> Value) {
            value += nextValue()
        }
    }
    

I want when I scroll up the Text ("Hello") will stay fixed, and the text "Welcome " will move up to be on the same line as Text("Hello").

David
  • 57
  • 5

1 Answers1

0

welcome to the community. From what I see there are two ways to do this, both requiring a Binding<Bool>. Let me explain.

  1. You will need to add a Binding<Bool> variable to your TagLineView where depending on the value you can display different views based on the Binding<Bool value. For this, you can use a separate HStack and VStack with your Text embedded in them. But I find this redundant so, istead you can use Text concatenation. See the code below for your TagLineView View.
struct TagLineView: View {

    @Binding var isHStacked: Bool

    var body: some View {
        Text("Hello")
            .font(.title)
            .fontWeight(.bold) + Text(isHStacked ? " " : "\n") +  // Adding a newline or adding a space based on the orientation of the stack
            Text("Welcome!")
            .font(.title)
    }
}
  1. After adding the above code, you will need to toggle the isHStacked variable when the user scrolls up or down. You can check the following threads to find a suitable answer for your use case

I used the first thread. For that, you will need to create a PreferenceKey

struct ContentView: View {
 
    @State var didScrollUp: Bool = false
    var body: some View {
        NavigationView {
            ScrollView {
                ZStack {
                    .
                    .
                    .
                    }.background(GeometryReader {
                        Color.clear.preference(key: ViewOffsetKey.self,
                                               value: -$0.frame(in: .named("scroll")).origin.y)
                    })
                    .onPreferenceChange(ViewOffsetKey.self) { didScrollUp = $0 > 5 ? true : false }
                }
 
            }
            .coordinateSpace(name: "scroll")
        }
 
    }
}
 
// Preference key
struct ViewOffsetKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}
 

The entire codebase can be found here

And once you toggle the views, the result will look similar to the gif below,

George
  • 25,988
  • 10
  • 79
  • 133
Visal Rajapakse
  • 1,718
  • 1
  • 9
  • 15