본문 바로가기
app/swiftui

SwiftUI TextField Realtime Search in List

by nastorond 2022. 1. 19.

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