I’m working through the Socialcademy project and have reached the point where I’m trying to display a textfield for comments at the bottom of my view with a submit button to the right of it. For some reason the textfield doe not show, but the button does. Here is the struct:
private extension CommentsList {
struct NewCommentForm: View {
@StateObject var viewModel: FormViewModel<Comment>
var body: some View {
HStack {
TextField("Comment", text: $viewModel.content)
Button(action: viewModel.submit) {
if viewModel.isWorking {
ProgressView()
} else {
Label("Post", systemImage: "paperplane")
}
}
}
.alert("Cannot Post Comment", error: $viewModel.error)
.animation(.default, value: viewModel.isWorking)
.disabled(viewModel.isWorking)
.onSubmit(viewModel.submit)
}
}
}
If I comment out the button, the textfield is displayed. I have tried a solution someone else had for this problem using a NavigationView but that did not work, and I have not been able to find anything else online. I would greatly appreciate any help!
I’ve figured it out after a lot of trial and error! First, it turns out that using a stack, such as our HStack
, with a ToolbarItemGroup
can lead to potential layout issues which is the problem I was having. By changing HStack
to Group
, the TextField
and Button
can be grouped together and modified without their layout being affected. Second, the Group
containing the switch cases needs to be nested inside of a NavigationView
.
Here’s my solution:
// MARK: - CommentsList
struct CommentsList: View {
@StateObject var viewModel: CommentsViewModel
var body: some View {
NavigationView {
Group {
switch viewModel.comments {
case .loading:
ProgressView()
.onAppear {
viewModel.fetchComments()
}
case let .error(error):
EmptyListView(
title: "Cannot Load Comments",
message: error.localizedDescription,
retryAction: {
viewModel.fetchComments()
}
)
case .empty:
EmptyListView(
title: "No Comments",
message: "Be the first to leave a comment."
)
case let .loaded(comments):
List(comments) { comment in
CommentRow(viewModel: viewModel.makeCommentRowViewModel(for: comment))
}
.animation(.default, value: comments)
}
}
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
NewCommentForm(viewModel: viewModel.makeNewCommentViewModel())
}
}
}
.navigationTitle("Comments")
.navigationBarTitleDisplayMode(.inline)
}
}
// MARK: - NewCommentForm
private extension CommentsList {
struct NewCommentForm: View {
@StateObject var viewModel: FormViewModel<Comment>
var body: some View {
Group {
TextField("Comment", text: $viewModel.content)
Button(action: viewModel.submit) {
if viewModel.isWorking {
ProgressView()
} else {
Label("Post", systemImage: "paperplane")
}
}
}
.alert("Cannot Post Comment", error: $viewModel.error)
.animation(.default, value: viewModel.isWorking)
.disabled(viewModel.isWorking)
.onSubmit(viewModel.submit)
}
}
}
2 Likes
Omg thank you so much. you saved my life. I was going crazy not sure what was wrong with my code. T.T you are a life saver.