Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
911 views
in Technique[技术] by (71.8m points)

ios - SwiftUI: adding a View at the top of a dynamic List causes the View to shrink

I have a simple SwiftUI list that displays numbers asynchronously from a Combine publisher, when I add a View at the top of the list to act as a header view, I face a weird shrink or flicker happens for the header at the time the Content View gets redrawn when the data returns from the publisher:

here's the view-model class that has the publisher:

class ViewModel: ObservableObject {
    @Published var items: [Int] = []
    var subscriptions = Set<AnyCancellable>()

    init() {
            (0...10)
            .publisher
            .delay(for: .seconds(3), scheduler: DispatchQueue.main) //to simulate async call
            .sink { (value) in
            self.items.append(value)
        }
        .store(in: &subscriptions)
    }
}

and here's the ContentView struct that interacts with the above view model:

struct ContentView: View {
    @ObservedObject var viewModel: ViewModel
    var body: some View {

        List {
            VStack {
                Rectangle()
                Text("Some Text")
                Text("Some Other Very Long Text Some Other Some Other Long Text")
            }
            .background(Color.red)

            ForEach(viewModel.items, id: .self) {  item in
                Text("(item)")
            }
        }
    }
}

and here's the result:

enter image description here

I've tried to separate the VStack at the top of the list into an external View but nothing changed.

what's causing this weird shrink and is there a way to avoid it ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The fix is to use explicit list rows inset, something like as below...

List {
    VStack {
        Rectangle()
        Text("Some Text")
        Text("Some Other Very Long Text Some Other Some Other Long Text")
    }
    .background(Color.red)
    .listRowInsets(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)

    ForEach(viewModel.items, id: .self) {  item in
        Text("(item)")
    }
    .listRowInsets(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...