Ios 键入Swift时进行搜索

Ios 键入Swift时进行搜索,ios,swift,search,Ios,Swift,Search,我尝试在您键入Swift时实现搜索。它已经工作了,但我需要一些调整。我每打一封信就寄一封 func searchBar(searchBar: UISearchBar, textDidChange searchText: String) { let debouncedFindUser = debounce( Static.searchDebounceInterval, Static.q, findUser) debouncedFi

我尝试在您键入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的一个实现

我的问题是:

如果方法调用在特定时间内触发,我想“重新启动”。让我们夸张一点


只有在2秒钟内未键入搜索文本后,请求才会启动。因此,如果我是一个快速打字机,每0.5秒就要打一封信,那么请求就不会被触发,除非我暂停至少2秒。

你可以使用NSTimer。在textDidChange中启动或使计时器失效并重新启动计时器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")
}

您遇到的问题是,在每次调用
findUser
函数之前,都会对其进行去抖动。您的去抖动功能设置初始计时器和延迟,但由于您每次都调用它,因此初始计时器始终为“现在”。您应该只去抖动一次,以便闭包可以保持其捕获的最后执行时间

您只需要调用一次
debounce
,并将其存储为属性,如下所示:

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

    ...

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

    func findUser() {
        ...
    }
}

您只需要创建一个计时器

  func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    let text = searchText.trimmingCharacters(in: .whitespacesAndNewlines)

// Create a Timer in this or parent class.
    debounceTimer.invalidate() // just in case this button is tapped multiple times


    // start the timer
    debounceTimer = Timer.scheduledTimer(timeInterval: 0.8, target: self, selector: #selector(self.startSearch(_:)), userInfo: text, repeats: false)
}

func startSearch(_ timer: Timer) {
    if let searchText = timer.userInfo as? String {
        print("Searching: \(searchText)")

        // make your service call here ...
    }
}

谢谢你的回答,内特·库克。我用Jeremy的解决方案解决了我的问题,但可能我只是无法实现你的解决方案。^^如果我初始化lazy var,那么我就遇到了没有成员名“findUser”的问题。这可能是一种实例问题……为了避开未定义的变量,可以使用
lazy var debouncedFindUser:()->()=debounce(2.0,dispatch_get_main_queue(),self.findUser)
显式定义返回类型似乎可以解决这个问题,但不确定原因。为什么不直接使用
scheduledtimewiterval…
但是,
NSTimer
是一种更容易实现去抖动的方法,因为您可以取消计时器,但不能取消
dispatch\u