Home > Back-end >  Remove padding on TextEditor
Remove padding on TextEditor

Time:02-27

My custom text editor below once you click on the pen to edit, a new space appears so the text from before is not on the same line as the new one. How can I fix this? Here's a simple reproducible example:

struct SwiftUIView: View {
    
    @State var name: String = "test"
    @State var showEdit: Bool = true
    
    var body: some View {
        HStack {
            HStack {
                if(showEdit) {
                    CustomTextEditor.init(placeholder: "My unique name", text: $name)
                        .font(.headline)
                } else {
                    Text(name)
                        .font(.headline)
                }
            }
            
            Spacer()
            
            Button(action: {
                showEdit.toggle()
            }) {
                Image(systemName: "pencil")
                    .foregroundColor(.secondary)
            }
        }
    }
}

struct CustomTextEditor: View {
    let placeholder: String
    
    @Binding var text: String
    
    var body: some View {
        ZStack {
            if text.isEmpty  {
                Text(placeholder)
                    .foregroundColor(Color.primary.opacity(0.25))
            }
            TextEditor(text: $text)
        }.onAppear() {
            UITextView.appearance().backgroundColor = .clear
        }.onDisappear() {
            UITextView.appearance().backgroundColor = nil
        }
    }
}

I want it to have the same padding properies as inserting a simple Text("") so when I switch between Text("xyz") and TextEditor(text: $xyz) it has the same padding alignment. Right now TextEditor has a weird padding.

CodePudding user response:

You will drive yourself insane trying to line up a Text and a TextEditor (or a TextField, for that matter), so don't try. Use another, disabled, TextEditor instead, and control the .opacity() on the top one depending upon whether the bound variable is empty or not. Like this:

struct CustomTextEditor: View {
    
    @Binding var text: String
    @State private var placeholder: String

    init(placeholder: String, text: Binding<String>) {
        _text = text
        _placeholder = State(initialValue: placeholder)
    }
    
    var body: some View {
        ZStack {
            TextEditor(text: $placeholder)
                .disabled(true)
            TextEditor(text: $text)
                .opacity(text == "" ? 0.7 : 1)
        }
    }
}

This view will show the placeholder if there is no text, and hide the placeholder as soon as there is text.

Edit:

You don't need the button, etc. in your other view. It becomes simply:

struct SwiftUIView: View {
    @State var name: String = ""
    
    var body: some View {
        CustomTextEditor.init(placeholder: "My unique name", text: $name)
            .font(.headline)
            .padding()
    }
}

and if you need a "Done" button on the keyboard, change your CustomTextEditor() to this:

struct CustomTextEditor: View {
    
    @Binding var text: String
    @State private var placeholder: String

    @FocusState var isFocused: Bool
    
    init(placeholder: String, text: Binding<String>) {
        _text = text
        _placeholder = State(initialValue: placeholder)
    }
    
    var body: some View {
        ZStack {
            TextEditor(text: $placeholder)
                .disabled(true)
            TextEditor(text: $text)
                .opacity(text == "" ? 0.7 : 1)
                .focused($isFocused)
        }
        .toolbar {
            ToolbarItemGroup(placement: .keyboard) {
                Button {
                    isFocused = false
                } label: {
                    Text("Done")
                        .foregroundColor(.accentColor)
                        .padding(.trailing)
                }
            }
        }
    }
}
  • Related