2015-02-09 3 views
4

Я пытаюсь реализовать поиск по мере ввода, написанный в Swift. Он работает уже, но мне нужна настройка. Я отправляю каждое письмо, напечатанное вПоиск по мере ввода Swift

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) { 

    let debouncedFindUser = debounce(
     Static.searchDebounceInterval, 
     Static.q, 
     findUser) 

    debouncedFindUser() 
} 

запрос на бэкэнд.

func findUser() ->() { 
    SearchService.sharedInstance.getUser(0, numberOfItems: 100, 
     searchString: searchUserBar.text.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)! 
     , 
     success: {SearchUserDto -> Void in 
      if self.searchUserBar.text != nil { 
       self.updateSearch() 
      } 
     }, 
     failure: {NSError -> Void in 

    }) 
} 

Я попробовал реализацию DEBOUNCE здесь How can I debounce a method call?

Моей проблема:

Я хочу «перезагрузка» вызов метода, если он был вызван в течение определенного времени. Так что давайте немного преувеличиваем.

Запрос должен начаться только после того, как текст поиска не был введен в течение 2 секунд. Поэтому, если я быстро напечатаю и набираю каждые 0,5 секунды письмо, запрос никогда не должен запускаться, за исключением того, что я приостанавливаю не менее 2 секунд.

ответ

6

Вы можете использовать NSTimer. Запустите или недействите и перезапустите таймер в течение 2 секунд в текстовом элементе. Попросите таймер запустить метод findUser, когда он действительно появится.

var debounceTimer: NSTimer? 

@IBAction func test() { 
    if let timer = debounceTimer { 
     timer.invalidate() 
    } 
    debounceTimer = NSTimer(timeInterval: 2.0, target: self, selector: Selector("getUser"), userInfo: nil, repeats: false) 
    NSRunLoop.currentRunLoop().addTimer(debounceTimer!, forMode: "NSDefaultRunLoopMode") 
} 

func getUser() { 
    println("yeah") 
} 
+0

Почему бы просто не использовать '' scheduledTimerWithInterval ... Но да, 'NSTimer' является гораздо более простым способом реализовать debouncing, так как вы можете отменить таймер, но не можете отменить 'dispatch_after' –

1

Проблема у Вас есть то, что вы дребезг функции findUser перед вызовом его каждый раз. Функция debouncing устанавливает начальный таймер и задержку, но поскольку вы вызываете его каждый раз, начальный таймер всегда «сейчас». Вы должны дебютировать только один раз, чтобы закрытие могло сохранить свое зафиксированное последнее время.

Вы хотите вызвать только debounce один раз и сохранить его как свойство, например, так:

class MySearchController: ... { 
    lazy var debouncedFindUser = debounce(
     Static.searchDebounceInterval, 
     Static.q, 
     self.findUser) 

    ... 

    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) { 
     debouncedFindUser() 
    } 

    func findUser() { 
     ... 
    } 
} 
+0

Спасибо за ответ Nate Cook. Я решил свою проблему с решением Джереми, но, вероятно, я просто не могу реализовать свои. ^^ Если я инициализирую lazy var, то у меня проблема с не имеет имени участника 'findUser'. Вероятно, это своего рода проблема с экземпляром ... –

+0

Чтобы обойти переменную self undefined, вы можете использовать 'lazy var debouncedFindUser:() ->() = debounce (2.0, dispatch_get_main_queue(), self.findUser)' Явное определение тип возврата, похоже, разрешает его, не знаю почему. –

Смежные вопросы