skip to Main Content

I have the following SwiftUI view in my project that supports macOS 13+ and iOS 16+:

struct MyTextField: View {
    
    var placeholder: LocalizedStringKey
    #if os (iOS)
    var keyboardType: UIKeyboardType = .default
    #endif
}

at call site I can’t use a single initializer like this for both operating systems:

MyTextField(placeholder: "some placeholder",
                                   keyboardType: .asciiCapableNumberPad,
                                   hasToolbar: true)

as it gives a syntax error for macOS as it cannot find the keyboardType argument in the init signature, I know that I can check for the os at call site using #if os(iOS) and provide different init for the target os, but it’s cumbersome when I have a huge form of text fields where I should determine the keyboard type for every text field, is there a way to call one init at call site to support the 2 operating systems in this case ?

2

Answers


  1. Create your custom enum class with the UIKeyboardTypes.

    enum MyKeyboardType {
        case `default`,
             asciiCapableNumberPad,
             // ...
    
    #if os(iOS)
        // Consider changing this method to be more generic and scalable
        func getUIType() -> UIKeyboardType {
            switch self {
            case .default:
                return .default
            case .asciiCapableNumberPad:
                return .asciiCapableNumberPad
            // ...
            }
        }
    #endif
    }
    

    And use it in your initializer:

    struct MyTextField: View {
        
        var placeholder: LocalizedStringKey
        var keyboardType: MyKeyboardType?
        
        init(placeholder: LocalizedStringKey,
             keyboardType: MyKeyboardType = .default) {
            
            self.placeholder = placeholder
    #if os(iOS)
            self.keyboardType = keyboardType
    #endif
        }
    }
    
    Login or Signup to reply.
  2. If MyTextField wraps a normal SwiftUI TextField, then you don’t need to pass keyboardType as a parameter. You can use the existing keyboardType modifier, like this:

    MyTextField(placeholder: “whatever”)
        #if os(iOS)
        .keyboardType(.asciiCapableNumberPad)
        #endif
    

    The keyboardType modifier applies to all descendants of the MyTextField.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search