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").

2
  • Can you show your current code? Commented Sep 21, 2021 at 2:55
  • @aheze I have updated the above Commented Sep 21, 2021 at 3:20

1 Answer 1

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,

Sign up to request clarification or add additional context in comments.

7 Comments

Please. Can you update all the current code here?
As in? You want the entire code in my answer?
Yes..can you help me ?
Yes, I have edited my answer. Check it out
Variable Ishstacked in TaglineView, don't you initialize it in contentview ()?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.