iOS TableView在搜索时自动拖动

时间:2018-08-19 09:27:30

标签: ios swift uitableview uiscrollview uisearchbar

我有一个带有搜索栏和分页的表格视图

    class DelegatesViewController: UIViewController {

    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var emptyDataLabel: UILabel!

    private var paginationManager: PaginationUIManager?
    private var delegates: [DelegateCellModel] = []

    private var filterDelegates: [DelegateCellModel] = [] {
        didSet {
            self.showNoDataLabel()
        }
    }

    private var isDragging: Bool {
        return self.tableView.isDragging
    }

    private struct Segue {
        static let delegateDetail = "DelegateDetailVCSegueId"
    }

    private var isEmptyData: Bool {
        if let event = DataModel.shared.currentEvent,
           let delegates = event.delegates {
            return delegates.isEmpty
        }
        return true
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupUI()
        self.fetchLocalItems()
        self.setupPagination()
        self.fetchItems()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func backAction(_ sender: Any) {
        self.navigationController?.popViewController(animated: true)
    }
}

extension DelegatesViewController: UITableViewDelegate, UITableViewDataSource {

    private func setupUI() {
        self.searchBar.delegate = self
        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.register(DelegateTableViewCell.defaultNib,
                                forCellReuseIdentifier: DelegateTableViewCell.defaultReuseIdentifier)
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return tableView.bounds.height / 4
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.filterDelegates.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(
            withIdentifier: DelegateTableViewCell.defaultReuseIdentifier
        ) as! DelegateTableViewCell
        if indexPath.row <= self.filterDelegates.count - 1 {
            cell.item = self.filterDelegates[indexPath.row]
        }
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let model = self.filterDelegates[indexPath.row]
        self.performSegue(withIdentifier: Segue.delegateDetail, sender: model)
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print(scrollView.description)
    }
}

extension DelegatesViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        switch (segue.identifier, segue.destination, sender) {
        case (Segue.delegateDetail?,
              let vc as DelegateDetailViewController,
              let model as DelegateCellModel):
            vc.sourceModel = model
        default:
            break
        }
        super.prepare(for: segue, sender: sender)
    }
}

extension DelegatesViewController: UISearchBarDelegate {

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        self.filter(searchText: searchText)
    }

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        searchBar.resignFirstResponder()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        self.resetData()
    }

    private func filter(searchText: String) {
        if searchText.isEmpty {
            self.filterDelegates = self.delegates
        } else {
            self.filterDelegates = self.delegates.filter {
                $0.delegate.fullName.lowercased().contains(searchText.lowercased())
            }
        }
        self.tableView.reloadData()
    }

    private func resetData() {
        searchBar.text = nil
        searchBar.resignFirstResponder()
        self.filterDelegates = self.delegates
        self.tableView.reloadData()
    }
}

extension DelegatesViewController {

    private func fetchLocalItems() {
        DataModel.shared.currentEvent?.fetchLocalDelegates { [weak self] (result) in
            switch result {
            case .success(let delegate):
                self?.handleRefreshData(items: delegate.list)
            case .failure:
                break
            }
        }
    }

    private func fetchDelegates(completion: @escaping (Bool) -> Void) {
        if !self.isDragging, self.isEmptyData { self.showLoader() }
        self.searchBar.isUserInteractionEnabled = false
        DataModel.shared.currentEvent?.fetchDelegates { [weak self] (result) in
            guard let this = self else { return }
            this.hideLoader()
            self?.searchBar.isUserInteractionEnabled = true
            switch result {
            case .success(let result):
                self?.handleRefreshData(items: result.list)
                completion(true)
            case .failure(let error):
                self?.tableView.setContentOffset(.zero, animated: true)
                completion(false)
                self?.handle(error: error)
            }
        }
    }

    private func showNoDataLabel() {
        self.emptyDataLabel.isHidden = !self.delegates.isEmpty
    }
}

extension DelegatesViewController: PaginationUIManagerDelegate {

    func setupPagination() {
        self.paginationManager = PaginationUIManager(scrollView: self.tableView,
                                                     pullToRefreshType: .basic)
        self.paginationManager?.delegate = self
    }

    private func fetchItems() {
        self.paginationManager?.load { }
    }


    func refreshAll(completion: @escaping (Bool) -> Void) {
        self.fetchDelegates(completion: completion)
    }

    func handleRefreshData(items: [Delegate]) {
        self.delegates = items.map { DelegateCellModel(delegate: $0) }
        self.delegates.sort { $0.delegate.fullName < $1.delegate.fullName }
        self.filter(searchText: self.searchBar.text ?? "")
    }

    func loadMore(completion: @escaping (Bool) -> Void) {
        completion(false)
    }
}

enter image description here

但是当我搜索时,它会自动向下拖动。搜索是本地搜索;没有API调用。

enter image description here

即使在搜索时我在scrollViewDidScrollDelegate上添加了日志,

我在做什么错了?

0 个答案:

没有答案