swiftswiftuiswift3uikitswiftui-view

I am unable to use a spacer to push a text view to the top of my swift ui VStack view, when adding UI wrappers


I have got a piece of code below but the issue is the text field is positioned in the middle of the view and when I add spacers below to push the textfield to the top of the view, it doesn't get pushed the textfield to the top of the view but rather it only moves when i specify the minLength of the spacer but we know this isnt the right approach because different phones have different dimensions. so can someone provide a proper fix to this or spot what is hindering spacer() from working

import SwiftUI

struct FocusedTextField: UIViewRepresentable {
    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: FocusedTextField

        init(_ parent: FocusedTextField) {
            self.parent = parent
        }

        func textFieldDidEndEditing(_ textField: UITextField) {
            parent.text = textField.text ?? ""
        }
    }

    @Binding var text: String
    @Binding var isFocused: Bool

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

    func makeUIView(context: UIViewRepresentableContext<FocusedTextField>) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.delegate = context.coordinator
        textField.textColor = .black
        textField.placeholder = "Enter some text"
        return textField
    }

    func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<FocusedTextField>) {
        uiView.text = text
        if isFocused && !uiView.isFirstResponder {
            uiView.becomeFirstResponder()
        }
    }
}

struct testList: View {
    @State private var text: String = ""
    @State private var isFocused: Bool = false

    var body: some View {
        VStack{
            
            FocusedTextField(text: $text, isFocused: $isFocused)
            
        }
        .onAppear {
            self.text = ""
            self.isFocused = true
        }
        .padding()
    }
}


struct textList_Previews: PreviewProvider {
    static var previews: some View {
        testList()
    }
}


Solution

  • For vertical wrap you need to make add some code in makeUIView:

    textField.setContentHuggingPriority(.required, for: .vertical)
    

    and add spacer() in testList()

    Try below code:

    struct FocusedTextField: UIViewRepresentable {
        class Coordinator: NSObject, UITextFieldDelegate {
            var parent: FocusedTextField
            
            init(_ parent: FocusedTextField) {
                self.parent = parent
            }
            
            func textFieldDidEndEditing(_ textField: UITextField) {
                parent.text = textField.text ?? ""
            }
        }
        
        @Binding var text: String
        @Binding var isFocused: Bool
        
        func makeCoordinator() -> Coordinator {
            Coordinator(self)
        }
        
        func makeUIView(context: UIViewRepresentableContext<FocusedTextField>) -> UITextField {
            let textField = UITextField(frame: .zero)
            textField.delegate = context.coordinator
            textField.textColor = .black
            textField.placeholder = "Enter some text"
            textField.setContentHuggingPriority(.required, for: .vertical)   //<---------------here
            return textField
        }
        
        func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<FocusedTextField>) {
            uiView.text = text
            if isFocused && !uiView.isFirstResponder {
                uiView.becomeFirstResponder()
            }
        }
    }
    
    struct testList: View {
        @State private var text: String = ""
        @State private var isFocused: Bool = false
        
        var body: some View {
            VStack{
                
                FocusedTextField(text: $text, isFocused: $isFocused)
                
                Spacer()    //<--------- here
                    
                
            }
            .onAppear {
                self.text = ""
                self.isFocused = true
            }
            .padding()
        }
    }
    
    
    struct textList_Previews: PreviewProvider {
        static var previews: some View {
            testList()
        }
    }