Socialcademy 10: Textfield is not appearing in the view

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.