Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a multiline TextField in SwiftUi ? like the notes app?

Tags:

swift

swiftui

I want to create a multiline textfield that automatically ads line breaks and with scroll view, just like the notes app, is there any direct way we can do this in SwiftUI ?

like image 925
BIBIN BENNY Avatar asked Aug 27 '19 17:08

BIBIN BENNY


People also ask

What is multiline TextField?

A multline text input field stores a string as its value and a string as its text. Its value is always a valid string, while its text could be any string entered into its editor. Unlike a text input field, this field also supports newline characters entered in the editor.


3 Answers

This works in Xcode Version 11.0 beta 6:

import SwiftUI

struct ContentView: View {
     @State var text = ""

       var body: some View {
        VStack {
            Text("text is: \(text)")
            TextView(
                text: $text
            )
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        }

       }
}

struct TextView: UIViewRepresentable {
    @Binding var text: String

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UITextView {

        let myTextView = UITextView()
        myTextView.delegate = context.coordinator

        myTextView.font = UIFont(name: "HelveticaNeue", size: 15)
        myTextView.isScrollEnabled = true
        myTextView.isEditable = true
        myTextView.isUserInteractionEnabled = true
        myTextView.backgroundColor = UIColor(white: 0.0, alpha: 0.05)

        return myTextView
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.text = text
    }

    class Coordinator : NSObject, UITextViewDelegate {

        var parent: TextView

        init(_ uiTextView: TextView) {
            self.parent = uiTextView
        }

        func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
            return true
        }

        func textViewDidChange(_ textView: UITextView) {
            print("text now: \(String(describing: textView.text!))")
            self.parent.text = textView.text
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
like image 50
Meo Flute Avatar answered Nov 13 '22 07:11

Meo Flute


You can use

TextEditor(text: $text)
like image 24
Mert Köksal Avatar answered Nov 13 '22 07:11

Mert Köksal


What you're looking for is essentially a UITextView. There is no current equivalent in SwiftUI, so you'll have to use a UIViewRepresentable struct to achieve this. See Apple's SwiftUI + UIKit tutorial for how to wrap UIKit views and view controllers for use in SwiftUI and see this question for a possible implementation (and solution to an easy to overlook detail.)

like image 24
Procrastin8 Avatar answered Nov 13 '22 06:11

Procrastin8