【问题标题】:Search as you type Swift键入 Swift 时进行搜索
【发布时间】:2018-08-05 18:07:09
【问题描述】:

我尝试在您用 Swift 编写时实现 Search。它已经工作了,但我需要一些调整。我用输入的每封信发送

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 秒。

【问题讨论】:

    标签: ios swift search


    【解决方案1】:

    您可以使用 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")
    }
    

    【讨论】:

    • 为什么不直接使用scheduledTimerWithInterval... 但是,NSTimer 是一种更容易实现去抖动的方法,因为您可以取消计时器但不能取消 dispatch_after
    【解决方案2】:

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

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

    class MySearchController: ... {
        lazy var debouncedFindUser = debounce(
            Static.searchDebounceInterval,
            Static.q,
            self.findUser)
    
        ...
    
        func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
            debouncedFindUser()
        }
    
        func findUser() {
            ...
        }
    }
    

    【讨论】:

    • 感谢 Nate Cook 的回答。我用 Jeremy 的解决方案解决了我的问题,但可能我无法实现你的解决方案。^^ 如果我初始化惰性 var,那么我会遇到没有成员名称“findUser”的问题。这可能是一种实例问题...
    • 绕过 self undefined 变量,可以使用lazy var debouncedFindUser : () -> () = debounce(2.0, dispatch_get_main_queue(), self.findUser) 显式定义返回类型似乎可以解决它,不知道为什么。
    【解决方案3】:

    您唯一需要做的就是创建一个计时器

      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 ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 1970-01-01
      • 2014-01-04
      相关资源
      最近更新 更多