Last active
March 28, 2020 17:41
-
-
Save tarangpatel/46e7aabfb790e69f2f21781a44a78390 to your computer and use it in GitHub Desktop.
[Throttling] #throttling #SearchBar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
public class SearchBar: UISearchBar, UISearchBarDelegate { | |
/// Throttle engine | |
private var throttler: Throttler? = nil | |
/// Throttling interval | |
public var throttlingInterval: Double? = 0 { | |
didSet { | |
guard let interval = throttlingInterval else { | |
self.throttler = nil | |
return | |
} | |
self.throttler = Throttler(seconds: interval) | |
} | |
} | |
/// Event received when cancel is pressed | |
public var onCancel: (() -> (Void))? = nil | |
/// Event received when a change into the search box is occurred | |
public var onSearch: ((String) -> (Void))? = nil | |
public override func awakeFromNib() { | |
super.awakeFromNib() | |
self.delegate = self | |
} | |
// Events for UISearchBarDelegate | |
public func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { | |
self.onCancel?() | |
} | |
public func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { | |
self.onSearch?(self.text ?? "") | |
} | |
public func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { | |
guard let throttler = self.throttler else { | |
self.onSearch?(searchText) | |
return | |
} | |
throttler.throttle { | |
DispatchQueue.main.async { | |
self.onSearch?(self.text ?? "") | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Throttler.swift | |
// | |
// Created by Daniele Margutti on 10/19/2017 | |
// | |
// web: http://www.danielemargutti.com | |
// email: hello@danielemargutti.com | |
// | |
// Updated by Ignazio Calò on 19/10/2017. | |
import UIKit | |
import Foundation | |
public class Throttler { | |
private let queue: DispatchQueue = DispatchQueue.global(qos: .background) | |
private var job: DispatchWorkItem = DispatchWorkItem(block: {}) | |
private var previousRun: Date = Date.distantPast | |
private var maxInterval: Int | |
init(seconds: Int) { | |
self.maxInterval = seconds | |
} | |
func throttle(block: @escaping () -> ()) { | |
job.cancel() | |
job = DispatchWorkItem(){ [weak self] in | |
self?.previousRun = Date() | |
block() | |
} | |
let delay = Date.second(from: previousRun) > maxInterval ? 0 : maxInterval | |
queue.asyncAfter(deadline: .now() + Double(delay), execute: job) | |
} | |
} | |
private extension Date { | |
static func second(from referenceDate: Date) -> Int { | |
return Int(Date().timeIntervalSince(referenceDate).rounded()) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// value to search for an interval >= 0.5 seconds. | |
searchBar.throttlingInterval = 0.5 | |
// Receive events for search | |
searchBar.onSearch = { text in | |
if text.length == 0 { // user tapped the 'X' button | |
// restore our plain list without search filter | |
} else if textToSearch.length > MIN_CHARS_TO_SEARCH { | |
// A valid search (where length > MIN_CHARS_TO_SEARCH) must be | |
// performed. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment