I followed ViewThatFits tutorial mentioned here, to show and hide a text according to its length and the available space as follows:
struct ExpandableText: View {
    let text: String
    let initialLineLimit: Int
    @State private var isExpanded = false
    @State private var showButton = false
    
    var button: Button<Text> {
        if isExpanded {
            return Button("Show less") {
                isExpanded = false
            }
        } else {
            return Button("Show more") {
                isExpanded = true
            }
        }
    }
    
    var body: some View {
        Text(text)
            .lineLimit(isExpanded ? nil : initialLineLimit)
            .background {
                ViewThatFits(in: .vertical) {
                    Text(text)
                        .hidden()
                    Color.clear
                        .onAppear {
                            showButton = true
                        }
                }
            }
        if showButton {
            button
        }
    }
}
This works fine if I use a VStack with ScrollView like this (copy-paste the code to try it out):
struct ContentView: View {
    
    var items = ["this is test text",
                 
                 "this is test text this is test text",
                 
                 " this is test text this is test text this is test text",
                 
                 "this is test text this is test text this is test text this is test text",
                 
                 "this is test text this is test text this is test text this is test text this is test text",
                 
                 "this is test text this is test text this is test text this is test text this is test text this is test text",
                 
                 "this is a small text",
                 
                 "this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text",
                 
                 "this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text",
                 
                 "this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text",
                 
                 "this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text this is test text",
    ]
    
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 0) {
                ForEach(items, id: \.self) { item in
                   ExpandableText(text: item, initialLineLimit: 2)
                        .padding()
                }
            }
        }
       
    }
}
However, when I use a LazyVStack instead of a VStack the "show more / less" button appears incorrectly if I scroll up and down, I couldn't find a clue why's this happening with the LazyVStack.
 
    