0

My problem is shown in the photo below:

enter image description here

I have tried using .fixedSize(horizontal:vertical) on the parent view and the textfield and no positive results.

TheTextField:

struct TheTextField: UIViewRepresentable {
    @Binding var text : String
    @Binding var placeholder : String
    
    func makeCoordinator() -> TheTextField.Coordinator {
        return TheTextField.Coordinator(parent1: self)
    }
    
    func makeUIView(context: UIViewRepresentableContext<TheTextField>) -> UITextView {
        let tview = UITextView()
        tview.isEditable = true
        tview.isUserInteractionEnabled = true
        tview.isScrollEnabled = false
        tview.text = placeholder
        tview.textColor = .gray
        tview.font = .systemFont(ofSize: 20)
        tview.delegate = context.coordinator
        return tview
    }
    
    func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<TheTextField>) {
        
    }
    
    class Coordinator : NSObject, UITextViewDelegate {
        var parent : TheTextField
        
        init(parent1 : TheTextField) {
            parent = parent1
        }
        
        func textViewDidChange(_ textView: UITextView) {
            self.parent.text = textView.text
        }
        
        func textViewDidBeginEditing(_ textView: UITextView) {
            textView.text = ""
            textView.textColor = .label
        }
    }
}

I want the textview to not expand and move the cursor to the next line, instead of messing up the parent's view.

Example:

Divider()
TheTextField(text: self.$imageToUpload.textCaption, placeholder: self.$placeholder).padding(.horizontal)
Spacer()
JGTechie
  • 55
  • 6
  • You should consider this https://stackoverflow.com/questions/56471973/how-do-i-create-a-multiline-textfield-in-swiftui/58639072#58639072 – Asperi Aug 28 '20 at 17:55
  • Thanks! I adopted my code to implement a dynamic height that will change based on the text length. Now, I am having issues with the background view disappearing and reappearing every time I type something – JGTechie Aug 28 '20 at 19:34

2 Answers2

1
import SwiftUI

struct UITextViewWrapper: UIViewRepresentable {
    @Binding var text : String
    @Binding var calculatedHeight: CGFloat
    
    func makeCoordinator() -> UITextViewWrapper.Coordinator {
        return UITextViewWrapper.Coordinator(text: $text, height: $calculatedHeight)
    }
    
    func makeUIView(context: UIViewRepresentableContext<UITextViewWrapper>) -> UITextView {
        let tview = UITextView()
        tview.isEditable = true
        tview.isUserInteractionEnabled = true
        tview.isScrollEnabled = false
        tview.textColor = .gray
        tview.font = .systemFont(ofSize: 20)
        tview.delegate = context.coordinator
        tview.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        return tview
    }
    
    func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<UITextViewWrapper>) {
        if uiView.text != self.text {
            uiView.text = self.text
        }
        if uiView.window != nil, uiView.isFirstResponder {
            uiView.becomeFirstResponder()
        }
    }
    
    static func recalculateHeight(view: UIView, result: Binding<CGFloat>){
        let newSize = view.sizeThatFits(CGSize(width: view.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
        if result.wrappedValue != newSize.height {
            DispatchQueue.main.async {
                result.wrappedValue = newSize.height // !! must be called asynchronously
            }
        }
    }
    
    class Coordinator : NSObject, UITextViewDelegate {
        var text : Binding<String>
        var calculatedHeight : Binding<CGFloat>
        
        init(text: Binding<String>, height: Binding<CGFloat>) {
            self.text = text
            self.calculatedHeight = height
        }
        
        func textViewDidChange(_ textView: UITextView) {
            text.wrappedValue = textView.text
            UITextViewWrapper.recalculateHeight(view: textView, result: calculatedHeight)
        }
        
        func textViewDidBeginEditing(_ textView: UITextView) {
            textView.text = ""
            textView.textColor = .label
        }
    }
}

I added functionality for changing the height of the dynamically depending on the length of the text per suggestion by Asperi.

JGTechie
  • 55
  • 6
0

You can easily edit label property from .storyboard file of our project. Change lines to 0 and line break property to your desired type and then you can have as many lines as you want your label to have.Check this image to see what I'm saying