TextField에 입력할 때 마다 실시간으로 filtering 해당하는 단어나 글자를 포함하는 list로 재구성해준다.
predictableValues 검색할 대상이 들어있는 list
predictedValues filtering이 된 list
textFieldInput 입력한 단어
struct PredictingTextField: View {
@Binding var predictableValues: Array<String>
@Binding var predictedValues: Array<String>
@Binding var textFieldInput: String
@State var predictionInterval: Double?
@State var textFieldTitle: String?
@State private var isBeingEdited: Bool = false
init(predictableValues: Binding<Array<String>>, predictedValues: Binding<Array<String>>, textFieldInput: Binding<String>, textFieldTitle: String? = "", predictionInterval: Double? = 0.1){
self._predictableValues = predictableValues
self._predictedValues = predictedValues
self._textFieldInput = textFieldInput
self.textFieldTitle = textFieldTitle
self.predictionInterval = predictionInterval
}
var body: some View {
TextField(self.textFieldTitle ?? "", text: self.$textFieldInput, onEditingChanged: { editing in self.realTimePrediction(status: editing)}, onCommit: { self.makePrediction()})
}
private func realTimePrediction(status: Bool) {
self.isBeingEdited = status
if status == true {
Timer.scheduledTimer(withTimeInterval: self.predictionInterval ?? 1, repeats: true) { timer in
self.makePrediction()
if self.isBeingEdited == false {
timer.invalidate()
}
}
}
}
private func capitalizeFirstLetter(smallString: String) -> String {
return smallString.prefix(1).capitalized + smallString.dropFirst()
}
private func makePrediction() {
self.predictedValues = []
if !self.textFieldInput.isEmpty{
for value in self.predictableValues {
if self.textFieldInput.split(separator: " ").count > 1 {
self.makeMultiPrediction(value: value)
}else {
if value.contains(self.textFieldInput) || value.contains(self.capitalizeFirstLetter(smallString: self.textFieldInput)){
if !self.predictedValues.contains(String(value)) {
self.predictedValues.append(String(value))
}
}
}
}
}
}
private func makeMultiPrediction(value: String) {
for subString in self.textFieldInput.split(separator: " ") {
if value.contains(String(subString)) || value.contains(self.capitalizeFirstLetter(smallString: String(subString))){
if !self.predictedValues.contains(value) {
self.predictedValues.append(value)
}
}
}
}
}
개별 페이지로 만들어서 사용해도 사용하면 편함
import SwiftUI
struct ContentView: View{
@State var predictableValues: Array<String>
@State var predictedValues: Array<String>
@State var textFieldInput: String
var body: some view{
PredictingTextField(predictableValues: self.$predictableValues, predictedValues: self.$predictedValues, textFieldInput: self.$textFieldInput)
List() {
ForEach(self.predictedValue, id: \.self){ value in
Text(value)
}
}
}
}
이런식으로 사용
아래 리스트를 선택형으로 만들고 싶으면 Text를 Button으로 변형
출처 https://github.com/simonloewe/TextFieldInputPrediction.git
'app > swiftui' 카테고리의 다른 글
SwiftUI AppStorage (0) | 2022.01.20 |
---|