问题描述
在我将子类从 UITableViewController 更改为 UIViewController 之前,我的代码正在运行。
切换的原因是我需要在我的 tableView 之上添加一个 collectionView。
但是现在单元格没有填充。快照仍在调用中,并且用户数组有其内容。
不确定为什么更改为 UIViewController 会使单元格停止填充。
import UIKit
private let reuseIdentifier = "UserCell"
private typealias UserDataSource = UITableViewDiffableDataSource<SearchController.Section,User>
private typealias UseRSSnapshot = NSDiffableDataSourceSnapshot<SearchController.Section,User>
class SearchController: UIViewController {
// MARK: - Properties
private var tableView = UITableView()
private var users = [User]()
private var filteredUsers = [User]()
private let searchController = UISearchController(searchResultsController: nil)
private var inSearchMode: Bool {
return searchController.isActive && !searchController.searchBar.text!.isEmpty
}
private var dataSource: UserDataSource!
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
configureSearchController()
configureTableView()
configureDataSource()
fetchUsers()
}
// MARK: - API
private func fetchUsers() {
showLoader(true)
UserService.fetchUsers { [weak self] users in
self?.showLoader(false)
self?.users = users
self?.createSnapshot(from: users)
}
}
// MARK: - Helpers
private func configureTableView() {
view.backgroundColor = .white
tableView.register(UserCell.self,forCellReuseIdentifier: reuseIdentifier)
tableView.rowHeight = 64
}
private func configureDataSource() {
dataSource = UserDataSource(tableView: tableView,cellProvider: { (tableView,indexPath,user) -> UITableViewCell? in
guard let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier,for: indexPath) as? UserCell else { fatalError() }
let user = self.inSearchMode ? self.filteredUsers[indexPath.row] : self.users[indexPath.row]
cell.viewmodel = UserCellviewmodel(user: user)
return cell
})
}
private func configureSearchController() {
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.placeholder = "Search"
navigationItem.searchController = searchController
definesPresentationContext = false
}
private func createSnapshot(from users: [User]) {
var snapshot = UseRSSnapshot()
snapshot.appendSections([.main])
snapshot.appendItems(users)
self.dataSource.apply(snapshot,animatingDifferences: false)
}
}
// MARK: - UITableViewDelegate
extension SearchController {
func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
guard let nonFilteredUser = dataSource.itemIdentifier(for: indexPath) else { return }
let user = inSearchMode ? self.filteredUsers[indexPath.row] : nonFilteredUser
let controller = ProfileController(user: user)
navigationController?.pushViewController(controller,animated: true)
}
}
// MARK: - UISearchResultsUpdating
extension SearchController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
guard let searchText = searchController.searchBar.text?.lowercased() else { return }
filteredUsers = users.filter({$0.username.lowercased().contains(searchText)
|| $0.fullname.lowercased().contains(searchText) })
let users = searchText.isEmpty ? self.users : filteredUsers
self.createSnapshot(from: users)
}
}
// MARK: - Sections
extension SearchController {
fileprivate enum Section {
case main
}
}
解决方法
表视图实际上并未添加到框架中,因此当我切换到 UIViewController 子类时,视图层次结构中实际上没有 tableView。我在 viewDidLoad 中添加了它,现在它是可见的。
忘记了 UIViewController 不会像 UITableViewController 子类那样在视图中自动添加 tableView。
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
configureSearchController()
configureTableView()
configureDataSource()
fetchUsers()
view.addSubview(tableView) // What I've missed to add.
tableView.frame = view.bounds
}