gurehbgui
gurehbgui

Reputation: 14674

How to get the TextEditor to display multiple lines?

I wanted the TextEditor to display eg. three lines of text. I have some sample code like this:

import SwiftUI

struct MultiLineText: View {
    @State var value: String
    @State var text: String
    
    var body: some View {
        Form {
            TextField("Title", text: $value)
            TextEditor(text: $text)
        }
    }
}

struct MultiLineText_Previews: PreviewProvider {
    static var previews: some View {
        MultiLineText(value: "my title", text: "some text")
    }
}

The problem is, that I always see only one line at a time for both controls (TextEditor and TextField) although I would like to have multiple lines displayed for the TextEditor.

How to realise this?

Upvotes: 3

Views: 2092

Answers (1)

Asperi
Asperi

Reputation: 257493

This is how Form works. The possible (simple) solution is to give TextEditor a frame

demo

TextEditor(text: $text)
    .frame(height: 80)

Update: more complicated case (dynamic calculation based on reference text, and taking into account dynamic font size)

Default

[demo1

Large font settings

[demo2

let lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."

struct ContentView: View {
    @State var value: String = lorem
    @State var text: String = lorem

    @State private var textHeight = CGFloat.zero
    var body: some View {
        Form {
            TextField("Title", text: $value)
            TextEditor(text: $text)
                .frame(minHeight: textHeight)
        }
        .background(
            Text("0\n0\n0")  // any stub 3 line text for reference
                .padding(.vertical, 6)  // TextEditor has default inset
                .foregroundColor(.clear)
                .lineLimit(3)
                .background(GeometryReader {
                    Color.clear
                        .preference(key: ViewHeightKey.self, value: $0.frame(in: .local).size.height)
                })
        )
        .onPreferenceChange(ViewHeightKey.self) { self.textHeight = $0 }
    }
}

The ViewHeightKey preference is taken from this my answer

Note: in-code fonts for reference Text and TextEditor should be used the same

Upvotes: 3

Related Questions