自动完成的 SwiftUI 示例

ami*_*n89 1 swift swiftui

我是 SwiftUI 初学者。我有一个 API 提供的“值”数组,我想要的是当我们点击“文本字段”中的字符时自动完成。您能给我提供一个可以执行此操作的 SwiftUI 代码示例吗?

我所说的自动完成的意思是:

在此输入图像描述

我有自己的价值观,而不是谷歌提供的价值观;

谢谢

Sim*_*mon 6

使用此存储库中的代码:https ://github.com/simonloewe/TextFieldInputPrediction

\n\n

并进行修改,以便预测以如下列表的形式返回:

\n\n
//\n//  ContentView.swift\n//  StackOverflow\n//\n//  Created by Simon L\xc3\xb6we on 04.04.20.\n//  Copyright \xc2\xa9 2020 Simon L\xc3\xb6we. All rights reserved.\n//\n\nimport SwiftUI\n\nstruct ContentView: View {\n\n    @State var textFieldInput: String = ""\n    @State var predictableValues: Array<String> = ["First", "Second", "Third", "Fourth"]\n    @State var predictedValue: Array<String> = []\n\n    var body: some View {\n        VStack(alignment: .leading){\n            Text("Predictable Values: ").bold()\n\n            HStack{\n                ForEach(self.predictableValues, id: \\.self){ value in\n                    Text(value)\n                }\n            }\n\n            PredictingTextField(predictableValues: self.$predictableValues, predictedValues: self.$predictedValue, textFieldInput: self.$textFieldInput)\n            .textFieldStyle(RoundedBorderTextFieldStyle())\n\n            // This is the only modification from the example in the repository\n            List() {\n                ForEach(self.predictedValue, id: \\.self){ value in\n                    Text(value)\n                }\n            }\n\n        }.padding()\n    }\n}\n\n\n/// TextField capable of making predictions based on provided predictable values\nstruct PredictingTextField: View {\n\n    /// All possible predictable values. Can be only one.\n    @Binding var predictableValues: Array<String>\n\n    /// This returns the values that are being predicted based on the predictable values\n    @Binding var predictedValues: Array<String>\n\n    /// Current input of the user in the TextField. This is Binded as perhaps there is the urge to alter this during live time. E.g. when a predicted value was selected and the input should be cleared\n    @Binding var textFieldInput: String\n\n    /// The time interval between predictions based on current input. Default is 0.1 second. I would not recommend setting this to low as it can be CPU heavy.\n    @State var predictionInterval: Double?\n\n    /// Placeholder in empty TextField\n    @State var textFieldTitle: String?\n\n    @State private var isBeingEdited: Bool = false\n\n    init(predictableValues: Binding<Array<String>>, predictedValues: Binding<Array<String>>, textFieldInput: Binding<String>, textFieldTitle: String? = "", predictionInterval: Double? = 0.1){\n\n        self._predictableValues = predictableValues\n        self._predictedValues = predictedValues\n        self._textFieldInput = textFieldInput\n\n        self.textFieldTitle = textFieldTitle\n        self.predictionInterval = predictionInterval\n    }\n\n    var body: some View {\n        TextField(self.textFieldTitle ?? "", text: self.$textFieldInput, onEditingChanged: { editing in self.realTimePrediction(status: editing)}, onCommit: { self.makePrediction()})\n    }\n\n    /// Schedules prediction based on interval and only a if input is being made\n    private func realTimePrediction(status: Bool) {\n        self.isBeingEdited = status\n        if status == true {\n            Timer.scheduledTimer(withTimeInterval: self.predictionInterval ?? 1, repeats: true) { timer in\n                self.makePrediction()\n\n                if self.isBeingEdited == false {\n                    timer.invalidate()\n                }\n            }\n        }\n    }\n\n    /// Capitalizes the first letter of a String\n    private func capitalizeFirstLetter(smallString: String) -> String {\n        return smallString.prefix(1).capitalized + smallString.dropFirst()\n    }\n\n    /// Makes prediciton based on current input\n    private func makePrediction() {\n        self.predictedValues = []\n        if !self.textFieldInput.isEmpty{\n            for value in self.predictableValues {\n                if self.textFieldInput.split(separator: " ").count > 1 {\n                    self.makeMultiPrediction(value: value)\n                }else {\n                    if value.contains(self.textFieldInput) || value.contains(self.capitalizeFirstLetter(smallString: self.textFieldInput)){\n                        if !self.predictedValues.contains(String(value)) {\n                            self.predictedValues.append(String(value))\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    /// Makes predictions if the input String is splittable\n    private func makeMultiPrediction(value: String) {\n        for subString in self.textFieldInput.split(separator: " ") {\n            if value.contains(String(subString)) || value.contains(self.capitalizeFirstLetter(smallString: String(subString))){\n                if !self.predictedValues.contains(value) {\n                    self.predictedValues.append(value)\n                }\n            }\n        }\n    }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

提供以下结果:

\n\n

在此输入图像描述

\n\n

在版本 11.5 和 iOS 13.5 上测试

\n