Мне удалось адаптировать ответ Свена Тана к моему существующему коду в Swift. В моем случае я отправляю строку в метод, который загружает результаты поиска асинхронно. Кроме того, я не использую UISearchBar, а просто старый UITextField.
var currentTempQuery = ""
...
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let t = textField.text {
let s: NSString = t
let newString = s.stringByReplacingCharactersInRange(range, withString: string).trim()
NSObject.cancelPreviousPerformRequestsWithTarget(self, selector:#selector(MyViewController.sendSearchRequest(_:)), object: currentTermQuery)
// Don't replace currentTermQuery until after the cancelPreviousPerformRequestWithTarget call
currentTermQuery = newString
performSelector(#selector(MyViewController.sendSearchRequest(_:)), withObject: newString, afterDelay: 1)
}
return true
}
Вот вызываемый селектор:
func sendSearchRequest(text: String?) {
// Call async search method here...
}
Способ работы cancelPreviousPerformRequestsWithTarget
заключается в том, что вам нужно передать ту же цель, селектор и объект, которые были переданы в вызове performSelector
, чтобы предыдущий запрос был отменен. В моей реализации, поскольку я передаю только строку, мне нужно сохранять текущую строку запроса между вызовами, чтобы я мог ссылаться на нее для отмены запросов.
Результат работает для ввода и удаления символов в моем UITextField. На одно изменение основного поискового запроса отправляется только один запрос.
Как я уже сказал, похоже на то, что написал Свен Тан, но немного другое использование. Надеюсь, это поможет некоторым людям.