首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用字符串初始化UIKeyboardType?

如何使用字符串初始化UIKeyboardType?
EN

Stack Overflow用户
提问于 2020-11-24 02:51:26
回答 2查看 106关注 0票数 0

我有一个jsondata结构,它是从包含以下内容的JSON文件构建的:

代码语言:javascript
复制
{
  inputFieldTitle: "Total Cost",
  keyboardType: "numberPad"
}

在我的代码中,如何使用属性keyboardType初始化UIKeyboardType枚举,以便在TextField上设置键盘类型?

通常我们这样做是为了得到一个numberPad键盘(SwiftUI):

代码语言:javascript
复制
TextField(jsondata.inputFieldTitle) { ... }
  .keyboardType(.numberPad)

但是在我的场景中,我不能使用.numberPad对keyboardType进行硬编码,我必须使用在jsondata中指定的内容,我如何使用该值在TextField上设置keyboardType?这显然不起作用,因为UIKeyboardType的类型是Int:

代码语言:javascript
复制
TextField(jsondata.inputFieldTitle) { ... }
  .keyboardType(UIKeyboardType(rawValue: jsondata.keyboardType))

有什么建议吗?谢谢。

EN

回答 2

Stack Overflow用户

发布于 2020-11-24 03:30:20

您可以使UIKeyboardType符合Decodable并实现您自己的自定义解码器方法:

代码语言:javascript
复制
extension UIKeyboardType: Decodable {
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            let rawValue = try container.decode(Int.self)
            guard let keyboardType = UIKeyboardType(rawValue: rawValue) else {
                throw DecodingError.dataCorruptedError(in: container, debugDescription: "invalid UIKeyboardType rawValue: \(rawValue)")
            }
            self = keyboardType
        } catch DecodingError.typeMismatch {
            let string = try container.decode(String.self)
            guard let keyboardType = UIKeyboardType(string) else {
                throw DecodingError.dataCorruptedError(in: container, debugDescription: "invalid UIKeyboardType string: \(string)")
            }
            self = keyboardType
        }
    }
    init?(_ string: String) {
        switch string {
        case "default":                 self = .default
        case "asciiCapable":            self = .asciiCapable
        case "numbersAndPunctuation":   self = .numbersAndPunctuation
        case "URL":                     self = .URL
        case "numberPad":               self = .numberPad
        case "phonePad":                self = .phonePad
        case "namePhonePad":            self = .namePhonePad
        case "emailAddress":            self = .emailAddress
        case "decimalPad":              self = .decimalPad
        case "twitter":                 self = .twitter
        case "webSearch":               self = .webSearch
        case "asciiCapableNumberPad":   self = .asciiCapableNumberPad
        case "alphabet":                self = .alphabet
        default: return nil
        }
    }
}

代码语言:javascript
复制
extension UIKeyboardType: Encodable {
    public func encode(to encoder: Encoder) throws {
        var encoder = encoder.singleValueContainer()
        let string: String
        switch self {
        case .default:                 string = "default"
        case .asciiCapable:            string = "asciiCapable"
        case .numbersAndPunctuation:   string = "numbersAndPunctuation"
        case .URL:                     string = "URL"
        case .numberPad:               string = "numberPad"
        case .phonePad:                string = "phonePad"
        case .namePhonePad:            string = "namePhonePad"
        case .emailAddress:            string = "emailAddress"
        case .decimalPad:              string = "decimalPad"
        case .twitter:                 string = "twitter"
        case .webSearch:               string = "webSearch"
        case .asciiCapableNumberPad:   string = "asciiCapableNumberPad"
        }
        try encoder.encode(string)
    }
}

代码语言:javascript
复制
extension DataProtocol {
    var string: String? { String(bytes: self, encoding: .utf8) }
}

游乐场测试:

代码语言:javascript
复制
struct Test: Codable {
    let inputFieldTitle: String
    let keyboardType: UIKeyboardType
}

代码语言:javascript
复制
let numberPadJSON = """
{
  "inputFieldTitle": "Total Cost",
  "keyboardType": "numberPad"
}
"""

代码语言:javascript
复制
do {
    let test = try JSONDecoder().decode(Test.self, from: Data(numberPadJSON.utf8))
    print(test.keyboardType.rawValue)  // 4
    let encoded = try JSONEncoder().encode(test)
    print(encoded.string ?? "")  // {"inputFieldTitle":"Total Cost","keyboardType":"numberPad"}
} catch {
    print(error)
}
票数 2
EN

Stack Overflow用户

发布于 2020-11-24 02:59:57

UIKeyboardType是-a Int,所以您不能使用rawValue,因为您的json值是string。

以下是可能的解决方案

代码语言:javascript
复制
extension UIKeyboardType {
    static private let types = ["numberPad": numberPad]   // << extend to all supported
    init(_ value: String) {
        if let result = Self.types[value] {
            self = result
        } else {
            self = .default
        }
    }
}

现在,您可以将其用作

代码语言:javascript
复制
TextField(jsondata.inputFieldTitle) { ... }
  .keyboardType(UIKeyboardType(jsondata.keyboardType))
//  .keyboardType(UIKeyboardType(jsondata.keyboardType ?? "")) // if optional
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64974560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档