Custom TextField not being called when user changes keyboard language layout through toggle switch

Viewed 79

I've managed to make a custom TextField that changes it's keyboard language layout when the user wants to enter foreign words on a foreign keyboard.

It only calls the custom text field when the view first loads. If I assign a string literal of "en-GB" to the variable that holds the desired keyboard language code, it is passed into the custom text view, and the keyboard is English British. If I assign German ("de-DE"), and compile the app again, the keyboard changes to German.

Ok, so I can start off with whatever keyboard I want, but in real world use the textfield keyboard will be configured to whatever the users locale is when the toggle switch is ON. When it's OFF, the keyboard layout will be for the language being learned. Typing in foreign words by using your native language's equivalent spelling is known as transliteration, and the toggle button to switch that on or off is the variable called 'transliteration', and is TRUE by default until the user changes it.

The problem seems to be that when the toggle switch is set to OFF, so the user can enter foreign words using the keyboard language related to the foreign word to be entered, the custom text view doesn't seem to get called so it can pass in the new value of keyboardLanguage (keyboardLanguage is assigned a keyboard language code of either the users local language or the foreign language they're trying to learn)

Here is the code with textfield and toggle button:

import SwiftUI
import Combine
import SwiftGoogleTranslate

struct AddThingAlert: View {

    @Binding var showingModal: Bool
    @State private var scale: CGFloat = 0.1
    @State private var nativeThing = ""
    @State private var foreignThing = ""
    @State private var conversationName = ""
    @State private var yOffset = 0
    @State private var buttonDisabled = true
    @State private var transliteration = true
    @State var keyboardLanguage: String = "en-GB"
    
    var language: Language
    var foreignPlaceholderText = ""
    var buttonText = "Ok"
    var action: (String, String, String) -> Void

    var body: some View {
        ZStack {
            Toggle("", isOn: $transliteration)
                .toggleStyle(CustomToggleStyle())
                .onChange(of: transliteration, perform: { value in
                    if transliteration {
                        keyboardLanguage = Locale.current.languageCode!
                    } else { keyboardLanguage = changeKeyboard.currentKeyboardLanguage(currentLanguage: language.name ?? "") }
                    print("keyboard language is: \(keyboardLanguage)")
                })
                .padding()
                .overlay(RoundedRectangle(cornerRadius: 6)
                .stroke(lineWidth: 1)
                .foregroundColor(transliteration ? .green : .gray))
            SpecificLanguageTextFieldView(placeHolder: "", language: keyboardLanguage, text: $foreignThing)
                .modifier(TextFieldClearButton(text: $foreignThing))
                .placeholder(when: foreignThing.isEmpty) {
                    Text("\(foreignPlaceholderText)").foregroundColor(.gray)
                }
                .onReceive(Just(foreignThing)) { foreignThing in
                    if self.nativeThing.count < 40 && self.foreignThing.count < 40 && !self.nativeThing.isEmpty && !self.foreignThing.isEmpty {
                        self.foreignThing = self.foreignThing.allowedCharacters(string: self.foreignThing)
                        buttonDisabled = false
                    } else { buttonDisabled = true }
                }
                .frame(width: screenSize.width * 0.7, height: 20, alignment: .center)
                .padding(5)
                .multilineTextAlignment(.center)
                .overlay(
                    RoundedRectangle(cornerRadius: 6)
                        .stroke(Color(UIColor.systemGray4), lineWidth: 1)
                )
                .font(.subheadline)
                .padding(.horizontal, 15)
                .padding(.bottom)
        }
    }
        
    func returnTextFieldInput() {
        self.action(nativeThing, foreignThing, conversationName)
        self.showingModal.toggle()
    }
}

And custom toggle style:

import SwiftUI

struct CustomToggleStyle: ToggleStyle {
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            Text(configuration.isOn ? "Transliteration is on" : "Transliteration is off")
                .foregroundColor(.gray)
            
            Spacer().frame(width: 20)
            
            Button(action: {
                configuration.isOn.toggle()
            }, label: {
                Image(systemName: configuration.isOn ? "speaker.fill" : "speaker.slash.fill")
                    .renderingMode(.template)
                    .foregroundColor(configuration.isOn ? .white : .red)
                    .font(.system(size: 50))
            })
            .buttonStyle(PlainButtonStyle())
        }
    }
}

And custom textfield:

import Foundation
import UIKit
import SwiftUI

class SpecificLanguageTextField: UITextField {
    
    var language: String? {
        didSet {
            if self.isFirstResponder{
                self.resignFirstResponder();
                self.becomeFirstResponder();
            }
        }
    }
    
    override var textInputMode: UITextInputMode? {
        if let language = self.language {
            for inputMode in UITextInputMode.activeInputModes {
                if let inputModeLanguage = inputMode.primaryLanguage, inputModeLanguage == language {
                    print("imput mode language is: \(inputModeLanguage)")
                    return inputMode
                }
            }
        }
        return super.textInputMode
    }
}

struct SpecificLanguageTextFieldView: UIViewRepresentable {

    let placeHolder: String
    var language: String
    @Binding var text: String

    func makeUIView(context: Context) -> UITextField{
        let textField = SpecificLanguageTextField(frame: .zero)
        textField.placeholder = self.placeHolder
        textField.text = self.text
        textField.language = self.language
        print("textfield language is: \(textField.language ?? "")")
        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
    }

}
0 Answers
Related