Ios API完成时重新加载TableView w/MVVM
我正在Swift 4中开发一个应用程序。我正在以编程方式构建我的应用程序——没有故事板 我有一个像这样的ViewControllerIos API完成时重新加载TableView w/MVVM,ios,swift,mvvm,Ios,Swift,Mvvm,我正在Swift 4中开发一个应用程序。我正在以编程方式构建我的应用程序——没有故事板 我有一个像这样的ViewController class SearchController: UITableViewController { private let cellID = "cellID" fileprivate let searchController = UISearchController(searchResultsController: nil) filepri
class SearchController: UITableViewController {
private let cellID = "cellID"
fileprivate let searchController = UISearchController(searchResultsController: nil)
fileprivate let viewModel = SearchViewModel(client: DiscogClient())
override func viewDidLoad() {
super.viewDidLoad()
setupSearchBar()
setupTableView()
}
fileprivate func setupSearchBar() -> Void {
navigationItem.hidesSearchBarWhenScrolling = false
navigationItem.searchController = searchController
searchController.searchBar.delegate = self
}
fileprivate func setupTableView() -> Void {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
tableView.tableFooterView = UIView()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.cellViewModels.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath)
return cell
}
}
extension SearchController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
viewModel.search(term: searchText)
}
}
import Foundation
import UIKit
class SearchViewModel {
var cellViewModels: [Result] = []
private let client: APIClient
var results: SearchResults? {
didSet {
for result in (results?.results)! {
cellViewModels.append(result)
}
}
}
var isLoading: Bool = false {
didSet {
showLoading?()
}
}
var showLoading: (() -> Void)?
var reloadData: (() -> Void)?
var showError: ((Error) -> Void)?
init(client: APIClient) {
self.client = client
}
func search(term: String) {
if let client = client as? DiscogClient {
let endpoint = DiscogsEndpoint.search(term: term, searchType: .release)
client.fetch(with: endpoint) { (either) in
switch either {
case .success(let results):
self.results = results
case .error(let error):
self.showError?(error)
}
}
}
}
}
我有一个像这样的视图模型
class SearchController: UITableViewController {
private let cellID = "cellID"
fileprivate let searchController = UISearchController(searchResultsController: nil)
fileprivate let viewModel = SearchViewModel(client: DiscogClient())
override func viewDidLoad() {
super.viewDidLoad()
setupSearchBar()
setupTableView()
}
fileprivate func setupSearchBar() -> Void {
navigationItem.hidesSearchBarWhenScrolling = false
navigationItem.searchController = searchController
searchController.searchBar.delegate = self
}
fileprivate func setupTableView() -> Void {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
tableView.tableFooterView = UIView()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.cellViewModels.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath)
return cell
}
}
extension SearchController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
viewModel.search(term: searchText)
}
}
import Foundation
import UIKit
class SearchViewModel {
var cellViewModels: [Result] = []
private let client: APIClient
var results: SearchResults? {
didSet {
for result in (results?.results)! {
cellViewModels.append(result)
}
}
}
var isLoading: Bool = false {
didSet {
showLoading?()
}
}
var showLoading: (() -> Void)?
var reloadData: (() -> Void)?
var showError: ((Error) -> Void)?
init(client: APIClient) {
self.client = client
}
func search(term: String) {
if let client = client as? DiscogClient {
let endpoint = DiscogsEndpoint.search(term: term, searchType: .release)
client.fetch(with: endpoint) { (either) in
switch either {
case .success(let results):
self.results = results
case .error(let error):
self.showError?(error)
}
}
}
}
}
当我在var results:SearchResults?
上选中didSet
时,我可以看到该值是通过我的APIClient
设置的
我要做的是指示ViewController表在设置该值后重新加载其数据
但我不确定如何实现这一点?我想我可以在cellViewModels上使用didSet
,并在我的ViewController上找到一种方法。这不起作用,或者我还不知道怎么做
我希望现在可以通过我的SearchController中的
viewModel.cellViewModels.count
更新行数您可以修改search
以接受完成块
func search(term: String, @escaping completion :() -> ()) {
if let client = client as? DiscogClient {
let endpoint = DiscogsEndpoint.search(term: term, searchType: .release)
client.fetch(with: endpoint) { (either) in
switch either {
case .success(let results):
self.results = results
completion()
case .error(let error):
self.showError?(error)
completion()
}
}
}
}
最后,您可以重新加载tableView
self.search(term: "abcd") {
self.tableView.reloadData()
}
人们可能经常要求您实现协议
,并在ViewModel和View之间建立通信。但是否使用块或协议始终是一个设计实现细节:)
希望这有帮助 您可以修改
搜索以接受完成块
func search(term: String, @escaping completion :() -> ()) {
if let client = client as? DiscogClient {
let endpoint = DiscogsEndpoint.search(term: term, searchType: .release)
client.fetch(with: endpoint) { (either) in
switch either {
case .success(let results):
self.results = results
completion()
case .error(let error):
self.showError?(error)
completion()
}
}
}
}
最后,您可以重新加载tableView
self.search(term: "abcd") {
self.tableView.reloadData()
}
人们可能经常要求您实现协议
,并在ViewModel和View之间建立通信。但是否使用块或协议始终是一个设计实现细节:)
希望这有帮助 当然可以!非常感谢你,工作得很顺利charm@petepete:很高兴我能帮上忙:)当然是的,很高兴为您服务!非常感谢你,工作得很顺利charm@petepete:我很高兴能帮上忙:)编码愉快