V8tr / KeyboardAvoidanceSwiftUI

How to move SwiftUI view up when keyboard appears https://www.vadimbulavin.com/how-to-move-swiftui-view-when-keyboard-covers-text-field/

Home Page:https://www.vadimbulavin.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ViewModifier increases height of view on load.

sethi-ishmeet opened this issue · comments

I applied the View Modifier on a HStack that includes a TextField and a Button. Although the keyboard adaptivity works fine, the initial height has increased and my content has been centred automatically.

            HStack(alignment: .bottom) {
                TextField("Write a Comment", text: $newComment)
                    .padding(.all, 10)
                    .font(.system(size: 12))
                    .background(Color.gray.opacity(0.1))
                    .cornerRadius(10)
                Button(action: {
                    print(self.newComment)
                }) {
                    Image(systemName: "paperplane.fill")
                        .font(.system(size: 20))
                }
                .disabled(newComment.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
            }
        .keyboardAdaptive()
            .padding(.all, 10)

Screen Shot 2020-04-23 at 11 32 13 PM

The above code is encapsulated in a VStack which also has a list above this HStack. Applying the ViewModifier on the Top Level View works perfectly. Why's that?

Also, Is there a way to account for the height of TabBarView in this? As My app is based on Tab View, the field goes higher than expected because of tab view.

commented

@sethi-ishmeet When you apply the modifier to the HStack it actually wraps your HStack in a GeometryReader. GeometryReader always tries to fill all available space, and it centers its content (your HStack) – that's why your view has increased in size.

@Coffeemate What would be the alternative? Pass the frameSize to the keyboardAdaptive?

@ercillagorka I observed that when you apply this ViewModifier to the parent view, it works as expected. However, I think that it should be applied to specific text field and not the whole view.

@Coffeemate many thanks for your explanation. I've added a note to the article based on your comment.

@V8tr Thanks for updating the article. It might also be worth mentioning that the View Modifier should be applied to the parent view vs. the Text Field or child view. For example, I changed where I was applying the View Modifier which fixed the issue. Below is the working code:

var body: some View {
    VStack {
            PagedList(viewModel: comments, id: \.id) { comment in
                CommentBubble(comment: comment)
                ForEach(comment.replies, id: \.id) { reply in
                    CommentBubble(comment: reply)
                        .padding(.leading, 20)
                }
            }
            
            HStack {
                TextField("Write a Comment", text: $newComment)
                    .padding(.all, 10)
                    .font(.system(size: 12))
                    .background(Color.gray.opacity(0.1))
                    .cornerRadius(10)
                    .disabled(self.comments.addCommentStatus == .loading)
                
                if self.comments.addCommentStatus == .loading {
                    Spinner()
                        .frame(width: 20, height: 20, alignment: .leading)
                } else {
                    Button(action: {
                        self.comments.addComment(self.newComment) { _ in
                            self.newComment = ""
                        }
                    }) {
                        Image(systemName: "paperplane.fill")
                            .font(.system(size: 20))
                    }
                    .disabled(newComment.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
                } 
                //.keyboardAdaptive() <-- applying view modifier here breaks the view like in above screenshot. However, when we apply it to the parent View as applied in this code, it works perfectly fine.

            }
            .padding(.all, 10)
        }
        .keyboardAdaptive() // <-- This works as expected
}

@V8tr Loved the article. Well written and allowed me to understand all. I'm still a beginner and really can appreciate when subtle things are explained well.

If the texfield is buried down the view Hierarchy it messes the geometry.frame(in: .global) as it doesn't seem to return the top level but the parent one.

I don't know why my iPhone 6s alway look like this
OverLap
IMG_9551