Home > Blockchain >  How could UILabel always be nil -- Unexpectedly found nil while implicitly unwrapping an Optional va
How could UILabel always be nil -- Unexpectedly found nil while implicitly unwrapping an Optional va

Time:04-22

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

enter image description here

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:

enter image description here

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
  • Related