Как создать текстовое поле автозаполнения в Swift

то, что я хочу иметь возможность создать, - Это автоматическое полное текстовое поле в iOS.

у меня есть форма для выбора клиента, в которой пользователь должен выбрать клиента один раз, используя текстовое поле . Что я хочу-это когда пользователь пишет первые три буквы в текстовое поле, я хочу обслуживание, чтобы выполнить запрос удаленного веб-сервиса с помощью введенного текста и представить результаты запроса в виде автозаполнения предложения.

ниже мой текущий код для моего приложения (iPad только.)

   import UIKit

    class AddClientViewController: UIViewController, UITextFieldDelegate {

        @IBOutlet weak var clientTextField:  UITextField!

        var foundList = [String]()


    override func viewDidLoad() {
        super.viewDidLoad()



         let listUrlString =  "http://bla.com/myTextField.php?field=(clientTextField)"
        let myUrl = NSURL(string: listUrlString);
        let request = NSMutableURLRequest(URL:myUrl!);
        request.HTTPMethod = "GET";

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in

            if error != nil {
                print(error!.localizedDescription)
                dispatch_sync(dispatch_get_main_queue(),{
                    AWLoader.hide()

                })

                return
            }


            do {

                let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray

                if let parseJSON = json {


                    self.foundList = parseJSON as! [String]

                }


        } catch {

            print(error)

        }
    }

    task.resume()
}

вот вывод json, который предоставляет моя веб-служба.

["123,John", "343,Smith", "345,April"]

разделенный запятыми, первый параметр -client ID и второй параметр-это имя клиента. John это имя, поэтому оно должно быть представлено в предложениях автозаполнения, которые, если они выбраны, установят текст clientTextField до John.

текущее текстовое содержимое clientTextField передается в качестве параметра GET в мой веб-сервис.

I не знаю, как это делать. Пользователь может печатать и еще не закончил, в то время как несколько запросов уже были отправлены.

спасибо.

iwillnot: я собрал ссылки на автозаполнение текстовых полей на Swift ниже.

ссылки на создание автозаполнения текстовых полей на Swift

https://github.com/mnbayan/AutocompleteTextfieldSwift (июль 2016)

http://github.com/Mazyod/MJAutoComplete (июль 2015)

http://github.com/hoteltonight/HTAutocompleteTextField (март 2015)

https://github.com/gaurvw/MPGTextField (июнь 2014)

заказано по последнему обновлению от 19 августа 2016 года.

2 ответов


Я сделал что-то подобное в мое приложение для поиска контактов. Я буду псевдо-код это для вас, чтобы понять концепцию:

1) захват символов, введенных в текстовое поле конечным пользователем

2) при некотором количестве введенных символов решите запросить сервер, чтобы вернуть все записи, которые соответствуют - выберите количество символов, которое вам удобно (я выбрал около 3-4 символов). Меньше отдачи больше, больше отдачи менее очевидно...до вас, perf и UX рассмотрения.

3) Поместите результаты этого запроса сервера в массив на клиенте. Это будет ваш суперсет, из которого вы будете предлагать свои предложения пользователю.

4) после каждого последующего символа, введенного в текстовое поле, вы теперь будете фильтровать массив (array.filter ()) по строке символов, введенной в эту точку. 5) TableView для.reloadData () против отфильтрованного массива при каждом введенном символе.

6) я использую переменную dataFlag для определения того, что источник данных для отображения в tableview в зависимости от того, что делает пользователь.

Примечание: вы запрашиваете сервер только один раз, чтобы минимизировать влияние perf

// this function is called automatically when the search control get user focus
func updateSearchResults(for searchController: UISearchController) {
  let searchBar = searchController.searchBar
  if searchBar.text?.range(of: "@") != nil {
    self.getUserByEmail(searchBar.text!)
  }
  if searchController.searchBar.text?.characters.count == 0 && dataFlag != "showParticipants" {
    dataFlag = "showInitSearchData"
    self.contacts.removeAll()
    self.participantTableView.reloadData()
  }
  if dataFlag == "showInitSearchData" && searchController.searchBar.text?.characters.count == 2 {
    self.loadInitialDataSet() {
      self.dataFlag = "showFilteredSearchData"
    }
  }
  if dataFlag == "showFilteredSearchData" {
    self.filterDataForSearchString()
  }

}

// filter results by textfield string
func filterDataForSearchString() {
  let searchString = searchController.searchBar.text
  self.filteredContacts =  self.contacts.filter({
    (contact) -> Bool in
    let contactText: NSString = "\(contact.givenName) \(contact.familyName)" as NSString

  return (contactText.range(of: searchString!, options: NSString.CompareOptions.caseInsensitive).location) != NSNotFound
  })

  DispatchQueue.main.async {
    self.participantTableView.reloadData()
  }  
}

Вы можете использовать в swift 4 ниже.

  1. создайте проект в swift 4
  2. перетащите текстовое поле и соединение в ViewController
  3. это будет выше, как изображение enter image description here
  4. вставить код ViewController

    class ViewController: UIViewController,UITextFieldDelegate {
    
      var myarray = ["Enamul Haque", "Ariful", "Mohsin"]
      var autoCompleteCharacterCount = 0
      var timer = Timer()
    
     @IBOutlet weak var txtUserId: UITextField!
    
    
     override func viewDidLoad() {
        super.viewDidLoad()
    
         txtUserId.delegate = self
       }
    
    
     //Setp 2
    
     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { //1
         var subString = (textField.text!.capitalized as NSString).replacingCharacters(in: range, with: string) // 2
    subString = formatSubstring(subString: subString)
    
       if subString.count == 0 { // 3 when a user clears the textField
         resetValues()
       } else {
          searchAutocompleteEntriesWIthSubstring(substring: subString) //4
        }
         return true
      }
      func formatSubstring(subString: String) -> String {
       let formatted = String(subString.dropLast(autoCompleteCharacterCount)).lowercased().capitalized //5
        return formatted
        }
    
    
    
     func resetValues() {
       autoCompleteCharacterCount = 0
      txtUserId.text = ""
      }
        //Step 3
       func searchAutocompleteEntriesWIthSubstring(substring: String) {
       let userQuery = substring
        let suggestions = getAutocompleteSuggestions(userText: substring) //1
    
       if suggestions.count > 0 {
             timer = .scheduledTimer(withTimeInterval: 0.01, repeats: false, block: { (timer) in //2
               let autocompleteResult =   self.formatAutocompleteResult(substring: substring, possibleMatches: suggestions) // 3
               self.putColourFormattedTextInTextField(autocompleteResult: autocompleteResult, userQuery : userQuery) //4
              self.moveCaretToEndOfUserQueryPosition(userQuery: userQuery) //5
          })
      } else {
           timer = .scheduledTimer(withTimeInterval: 0.01, repeats: false, block: { (timer) in //7
             self.txtUserId.text = substring
         })
           autoCompleteCharacterCount = 0
        }
       }
    
      //step 4
       func getAutocompleteSuggestions(userText: String) -> [String]{
        var possibleMatches: [String] = []
       for item in myarray { //2
        let myString:NSString! = item as NSString
        let substringRange :NSRange! = myString.range(of: userText)
    
        if (substringRange.location == 0)
        {
            possibleMatches.append(item)
        }
      }
       return possibleMatches
     }
    
          func putColourFormattedTextInTextField(autocompleteResult: String, userQuery : String) {
          let colouredString: NSMutableAttributedString = NSMutableAttributedString(string: userQuery + autocompleteResult)
      colouredString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red, range: NSRange(location: userQuery.count,length:autocompleteResult.count))
        self.txtUserId.attributedText = colouredString
    }
      func moveCaretToEndOfUserQueryPosition(userQuery : String) {
         if let newPosition = self.txtUserId.position(from: self.txtUserId.beginningOfDocument, offset: userQuery.count) {
           self.txtUserId.selectedTextRange = self.txtUserId.textRange(from: newPosition, to: newPosition)
       }
        let selectedRange: UITextRange? = txtUserId.selectedTextRange
        txtUserId.offset(from: txtUserId.beginningOfDocument, to: (selectedRange?.start)!)
     }
         func formatAutocompleteResult(substring: String, possibleMatches: [String]) -> String {
        var autoCompleteResult = possibleMatches[0]
      autoCompleteResult.removeSubrange(autoCompleteResult.startIndex..<autoCompleteResult.index(autoCompleteResult.startIndex, offsetBy: substring.count))
      autoCompleteCharacterCount = autoCompleteResult.count
      return autoCompleteResult
       }
    
    
    }