As many people encountered, I tried to build tableView
. I found many similar questions but it seems answers are not helping. I would be very grateful if anyone could help me. The problem I encountered:
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
EDIT based on new information full code and Json decoder:
struct CollegeInfo: Decodable {
let collegeList: [MyDataResults]
}
struct MyDataResults: Decodable {
let id: String
let name: String
let city: String
let state: String
}
class tableController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var myData = [MyDataResults]() // simulation of your array
let urlString = "https://api.collegeai.com/v1/api/autocomplete/colleges?api_key=b47484dd6e228ea2cc5e1bf6ca&query="
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .darkBlue
tableView.backgroundColor = .white
tableView.register(CollegeTableViewCell.self, forCellReuseIdentifier: "cellId") // register cell
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.separatorColor = .lightGray
view.addSubview(tableView)
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
// this is my extension to configure navigation bar, you can configure it as you want
configureNavigationBar(largeTitleColor: .red, backgoundColor: .black, tintColor: .red, title: "Sample", preferredLargeTitle: true)
fetchJson { [weak self] (res) in
switch res {
case .success(let dataResults):
dataResults.forEach { (dataresult) in
self?.myData.removeAll()
DispatchQueue.main.asyncAfter(deadline: .now() 0) {
self?.myData = dataresult.collegeList
self?.tableView.reloadData()
}
}
case .failure(let err):
print("Failed to fetch json", err)
}
}
}
fileprivate func fetchJson(completion: @escaping (Result<[CollegeInfo], Error >) -> ()) {
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { data, resp, err in
if let err = err {
completion(.failure(err))
return
}
do {
guard let data = data else { return }
let results = try JSONDecoder().decode(CollegeInfo.self, from: data)
//succesful
completion(.success([results]))
} catch let jsonErr {
completion(.failure(jsonErr))
}
}.resume()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
// Mark: - set number of rows with your array.count
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let myResults = myData[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! CollegeTableViewCell
cell.collegeName.text = myResults.name
cell.collegeGeo.text = "\(myResults.city), \(myResults.state)"
return cell
}
The cell:
class CollegeTableViewCell: UITableViewCell {
let collegeName: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = .systemFont(ofSize: 16, weight: .semibold)
label.backgroundColor = .clear
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let collegeGeo: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = .systemFont(ofSize: 14, weight: .semibold)
label.backgroundColor = .clear
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .ultraDark
let stackView = UIStackView(arrangedSubviews: [collegeName, collegeGeo]) // use stack view for automatic table view dimension
stackView.axis = .vertical
stackView.distribution = .fillEqually
stackView.spacing = 2
stackView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 20).isActive = true
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -20).isActive = true
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20).isActive = true
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The result:
CodePudding user response:
you're using the wrong bundle
name for dequeueReusableCell
.
instead of cell
use CollegeTableViewCell
it should be :
let cell = tableView.dequeueReusableCell(withIdentifier: "CollegeTableViewCell", for: indexPath) as! CollegeTableViewCell