1

News to SwiftUI so please bare with me :) I have a custom textfield setup as a struct in a separate file.

I would like to use onEditingChanged in my content view (the closure would be perfect), is this possible? I have tried with a binding but it isn't a great solution.

import Foundation
import SwiftUI

struct EntryField: View {
    
    var sfSymbolName: String
    var placeHolder: String
    var prompt: String
    @Binding var field: String
    var uptodate:Bool = false
    var showActivityIndicator:Bool = false
    @State var checkMarkOpacity = 0.9
    @Binding var editingChanged: Bool

    var body: some View {
        VStack(alignment: .leading) {
            
            HStack {
                Image(systemName: sfSymbolName)
                    .foregroundColor(.gray)
                    .font(.custom("SF Pro Light", size: 60))
                
                TextField(placeHolder, text: $field, onEditingChanged: { editing  in
                    
                    editingChanged = editing
                    
                }).autocapitalization(.none)
                    .keyboardType(.decimalPad)
                    .font(.custom("SF Pro Light", size: 60))
                    .placeholder(when: field.isEmpty) {
                        
                        Text("0,00")
                            .foregroundColor(.white)
                            .font(.custom("SF Pro Light", size: 60))
                    }
                
                    Image(systemName: "checkmark").opacity(uptodate ? 1 : 0)
                    .opacity(checkMarkOpacity)
                    .foregroundColor(.white)
                    .font(.custom("SF Pro Light", size: 40))
                    .onAppear(perform: {
                        
                        withAnimation(.easeIn(duration: 3.0).delay(2.0) ) {
                            checkMarkOpacity = 0
                        }
                        
                    })
            
                    .overlay(
                        
                        ProgressView()
                            .opacity(showActivityIndicator ? 1 : 0)
                            //.progressViewStyle(ShadowProgressViewStyle())
                            .progressViewStyle(RingProgressViewStyle(
                                configuration: .init(
                                    trackColor: .blue,
                                    fillColor: .white,
                                    lineWidth: 6)))
                           
                    )
                
            }
            .padding(8)
            
              .background(Color(UIColor.secondarySystemBackground))
              .clipShape(RoundedRectangle(cornerRadius:10))
            
            Text(prompt)
            .fixedSize(horizontal: false, vertical: true)
            .font(.caption)
        }
    }
}

and in my content view I have:

@State private var editingChanged: Bool = false

 EntryField(sfSymbolName: "eurosign.square", placeHolder: "", prompt: "Litre Price", field: $closestLitrePrice, uptodate: uptodate, showActivityIndicator: showActivityIndicator, editingChanged: $editingChanged)

thank you

jat
  • 183
  • 3
  • 14

1 Answers1

1

If you don't need it internally then you can pass closure directly from construction to TextField, like

let editingChanged: (Bool) -> Void      // << here !!

var body: some View {
  VStack(alignment: .leading) {

    HStack {
      Image(systemName: sfSymbolName)
        .foregroundColor(.gray)
        .font(.custom("SF Pro Light", size: 60))

      TextField(placeHolder, text: $field, 
                onEditingChanged: editingChanged)  // << here !!
        .autocapitalization(.none)

Asperi
  • 228,894
  • 20
  • 464
  • 690
  • Thankyou. That worked perfectly. That's very cool. What do you mean by internally ? – jat Jan 06 '22 at 07:58