-1

在我将子类从 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
    }
}
4

1 回答 1

-1

表格视图实际上没有添加到框架中,因此当我切换到 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
    }
于 2021-04-09T04:57:01.303 回答