I have created a list inside a scroll view that works fine when it has items, but I’ve noticed that when there are not items in the list that the scroll view is very narrow and it makes it hard to use the refreshabled. I have tried many solutions online such as using extra spacers, GeometryReady width, and other things but nothing seems to fix it.
Here is my code:
var body: some View {
GeometryReader { geo in
ZStack {
LinearGradient(stops: [
Gradient.Stop(color: Color("Cottage Green Tertiary"), location: 0.0),
Gradient.Stop(color: Color("Cottage Green Tertiary"), location: 0.85),
Gradient.Stop(color: Color("Cottage Dark Green"), location: 1.0)
], startPoint: .top, endPoint: .bottom)
.edgesIgnoringSafeArea(.all)
ScrollView(.vertical) {
ForEach(Array(self.viewModel.posts.enumerated()), id: \.element) { index, post in
VStack {
HStack {
if self.viewModel.canDeletePost(postIndex: index) {
Button {
self.viewModel.latestPostIndexSelectedToDelete = index
self.isShowingDeleteConfirm = true
} label : {
Image(systemName: "trash")
.foregroundStyle(Color("Cottage Dark Green"))
}
}
Spacer()
Text(getDateDescription(from: post.datePosted))
.font(.system(size: 12))
.padding(.bottom, 10)
}
Text(post.message)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.bottom, 10)
HStack {
Image(systemName: "person.fill")
.foregroundStyle(Color("Cottage Dark Green"))
Text(post.poster.name)
Spacer()
Button {
let impactMed = UIImpactFeedbackGenerator(style: .medium)
impactMed.impactOccurred()
if post.likers.contains(where: { $0 == self.userId }) {
self.viewModel.removeLike(from: self.userId, for: index)
} else {
self.viewModel.addLike(from: self.userId, for: index)
}
} label : {
if post.likers.contains(where: { $0 == self.userId }) {
Image(systemName: "hand.thumbsup.fill")
.foregroundStyle(Color("Cottage Dark Green"))
} else {
Image(systemName: "hand.thumbsup")
.foregroundStyle(Color("Cottage Dark Green"))
}
}
Text(String(post.likers.count))
}
}
.padding([.top, .bottom, .leading, .trailing], 10)
.background(Color("Cottage Green"))
.cornerRadius(10)
}
.padding([.top, .bottom, .leading, .trailing], 10)
.cornerRadius(10)
}
.frame(width: geo.size.width)
.alert(isPresented: $isShowingDeleteConfirm) {
Alert(
title: Text("Delete Post?"),
message: nil,
primaryButton: .destructive(Text("Delete")) {
self.viewModel.deletePost()
},
secondaryButton: .cancel()
)
}
.refreshable {
print("Do your refresh work here")
do {
try await viewModel.getPosts()
} catch {
}
}
if self.loadingState.isLoading {
ProgressView()
}
}
}
}
Here is what it looks like when it is empty:

Any help is appreciated as I am fairly new to SwiftUI! Thanks!




