边输入边搜索 Swift
Search as you type 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?
我的问题:
我想 "restart" 在特定时间内触发的方法调用。所以让我们夸张一点。
只有在 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
函数之前都对其进行去抖动。您的去抖功能设置了初始计时器和延迟,但由于您每次都调用它,因此初始计时器始终为 "now"。您应该只去抖动一次,以便闭包可以保持其捕获的上次执行时间。
您只想调用 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 ...
}
}
我尝试在您输入 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?
我的问题:
我想 "restart" 在特定时间内触发的方法调用。所以让我们夸张一点。
只有在 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
函数之前都对其进行去抖动。您的去抖功能设置了初始计时器和延迟,但由于您每次都调用它,因此初始计时器始终为 "now"。您应该只去抖动一次,以便闭包可以保持其捕获的上次执行时间。
您只想调用 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 ...
}
}