在UIViewController中使用TableViewCell的TableView未显示来自SearchBar的数据

3

我在显示从REST API获取的数据时遇到了问题。我可以无问题地检索数据,但是表格视图未显示数据。我如何将数据放入表格视图单元格中?

class SearchBSViewController: UIViewController {
    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var tableView: UITableView!

    lazy var tapRecognizer: UITapGestureRecognizer = {
        var recognizer = UITapGestureRecognizer(target:self, action: #selector(dismissKeyBoard))
        return recognizer
    }()

    var searchResults: [Service] = []
    let busStop = BusStop(odataMetadata: "", busStopCode: "", services: [])
    let queryService = QueryService()

    override func viewDidLoad() {
        super.viewDidLoad()
        alterLayout()
        searchBar.delegate = self
    }

    func alterLayout() {
        tableView.tableHeaderView = UIView()
        tableView.estimatedSectionHeaderHeight = 50
        navigationItem.titleView = searchBar
        searchBar.showsScopeBar = false
        searchBar.placeholder = "Search for bus stop by bus code"
    }
}

extension SearchBSViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.searchResults.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell: BusCell = tableView.dequeueReusableCell(withIdentifier: "BusCell", for: indexPath) as? BusCell else {
            return UITableViewCell()
        }

        let bus = searchResults[indexPath.row]
        cell.busNoLbl.text = bus.serviceNo
        return cell
    }

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

extension SearchBSViewController: UISearchBarDelegate {
    @objc func dismissKeyBoard() {
        searchBar.resignFirstResponder()
    }

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        dismissKeyBoard()
        print("Something")
        guard let searchText = searchBar.text, !searchText.isEmpty else { return }
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
        guard let searchNumber: Int = Int(searchText) else { return }
        queryService.GetBusStop(BusNo: searchNumber) {
            results in
            UIApplication.shared.isNetworkActivityIndicatorVisible  = false
            if let results = results {
                print(results.services?[1].nextBus?.estimatedArrival ?? 0)
                self.searchResults = results.services!
                self.tableView.reloadData()
                self.tableView.setContentOffset(CGPoint.zero, animated: false)
            }
        }
    }

    func position(for bar: UIBarPositioning) -> UIBarPosition {
        return .topAttached
    }

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        view.addGestureRecognizer(tapRecognizer)
    }

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        view.removeGestureRecognizer(tapRecognizer)
    }
}

class BusCell: UITableViewCell {
    @IBOutlet weak var busNoLbl: UILabel!
    @IBOutlet weak var firstBusLbl: UILabel!
    @IBOutlet weak var secBusLbl: UILabel!
    @IBOutlet weak var thirdBusLbl: UILabel!
    @IBOutlet weak var firstPrg: UIProgressView!
    @IBOutlet weak var secPrg: UIProgressView!
    @IBOutlet weak var thirdPrg: UIProgressView!
    @IBOutlet weak var firstType: UILabel!
    @IBOutlet weak var secType: UILabel!
    @IBOutlet weak var thirdType: UILabel!

    func configure(services: Service) {
        busNoLbl.text = services.serviceNo
        firstBusLbl.text = services.nextBus?.estimatedArrival
        secBusLbl.text = services.nextBus2?.estimatedArrival
        thirdBusLbl.text = services.nextBus3?.estimatedArrival
    }
}

class QueryService {
    typealias QueryResult = (BusStop?) -> ()

    var buses: BusStop = BusStop(odataMetadata: "", busStopCode: "", services: [])

    let defaultSession = URLSession(configuration: .default)

    var dataTask: URLSessionDataTask?

    func GetBusStop(BusNo: Int, completionBlock: @escaping QueryResult){
        dataTask?.cancel()
        var urlComponents = URLComponents(string: "http://datamall2.mytransport.sg/ltaodataservice/BusArrivalv2")!
        urlComponents.queryItems = [URLQueryItem(name: "BusStopCode", value: String(BusNo))]
        guard let url = urlComponents.url else { return}

        let urlRequest = Header(url: url) //input the header for authorization

        dataTask = defaultSession.dataTask(with: urlRequest) { (data, response, error) in
            if error != nil {
                print(error!.localizedDescription)
            }

            guard let data = data else { return }
            do {
                let BusStopData = try
                    JSONDecoder().decode(BusStop.self, from: data)

                DispatchQueue.main.async {
                    print("Queue")
                    completionBlock(BusStopData)
                }

            } catch let jsonError {
                print(jsonError)
            }
        }
        dataTask?.resume()

    }
}
2个回答

3
  • First thing is you need to set up a delegate and data source method for the table view. setup it in your view did load method

    tableView.delegate = self
    
    tableView.datasource = self
    
  • Second is you need to reload your table view after you hit your API call

    tableView.reloadData()
    

@Adwin,你需要检查数据重载方法、委托和数据源方法。 - Jarvis The Avenger

0
请在 alterLayout() 函数中设置 table view 的 delegatedatasource,例如:
tableView.delegate = self
tableView.datasource = self

谢谢!现在它可以显示在我的表格上了,尽管我不得不删除alterLayour()并在viewDidLoad()中添加tableView.delegate = self和tableView.datasource = self。 - Adwin Ang
是的,您也可以这样做。在重新加载 tableview 之前,我们需要设置数据源和委托。 - Anji Mendpara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接