0

I'm new with Xcode and Swift, following a tutorial and I found a problem when I called a UIView in front of a tableview so the user can create something new

NOTE: I already tried what this link shows with no luck to resolve my issue

I am using Xcode 11.3.1 and Swift

This is my code

Channel Model

import Foundation

struct Channel : Decodable {
    public private(set) var channelTitle: String!
    public private(set) var channelDescription: String!
    public private(set) var id: String!
}
Class ChannelCell

import UIKit

class ChannelCell: UITableViewCell {

    // Outlets
    @IBOutlet weak var channelName: UILabel!


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        if selected {
            self.layer.backgroundColor = UIColor(white: 1, alpha: 0.2).cgColor
        } else {
            self.layer.backgroundColor = UIColor.clear.cgColor
        }
    }

    func configureCell(channel: Channel) {
        let title = channel.channelTitle ?? ""
        channelName.text = "#\(title)"
    }
}

Channel View Controller

import UIKit

class ChannelVC: UIViewController, UITableViewDelegate, UITableViewDataSource {

    // Outlets

    @IBOutlet weak var loginBtn: UIButton!
    @IBOutlet weak var userImg: CircleImage!
    @IBOutlet weak var tableView: UITableView!
    @IBAction func prepareForUnwind(segue: UIStoryboardSegue) {}

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self <<<<<<<<< here I get the error message ***
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
        tableView.dataSource = self


        self.revealViewController()?.rearViewRevealWidth = self.view.frame.size.width - 60
        NotificationCenter.default.addObserver(self, selector: #selector(ChannelVC.userDataDidChange(_:)), name: NOTIF_USER_DATA_DID_CHANGE, object: nil)
    }

    override func viewDidAppear(_ animated: Bool) {
        setupUserInfo()
    }
When I pressed the add channel button comes the problem

    @IBAction func addChannelPressed(_ sender: Any) {
        if AuthService.instance.isLoggedIn {
            let addChannel = ChannelVC()
            addChannel.modalPresentationStyle = .custom
            present(addChannel, animated: true, completion: nil)
        } else {
            performSegue(withIdentifier: TO_LOGIN, sender: nil)
        }
    }

    @IBAction func loginBtnPressed(_ sender: Any) {
        if AuthService.instance.isLoggedIn {
            let profile = ProfileVC()
            profile.modalPresentationStyle = .custom
            present(profile, animated: true, completion: nil)
        } else {
           performSegue(withIdentifier: TO_LOGIN, sender: nil)
        }
    }

    @objc func userDataDidChange(_ notif: Notification) {
        setupUserInfo()
    }

    func setupUserInfo() {
        if AuthService.instance.isLoggedIn {
            loginBtn.setTitle(UserDataService.instance.name, for: .normal)
            userImg.image = UIImage(named: UserDataService.instance.avatarName)
            userImg.backgroundColor = UserDataService.instance.returnUIColor(components: UserDataService.instance.avatarColor)
        } else {
            loginBtn.setTitle("Login", for: .normal)
            userImg.image = UIImage(named: "menuProfileIcon")
            userImg.backgroundColor = UIColor.clear
        }
    }

    // Protocols for UITableViewDataSource
    // # of sections
    // # rows in the section
    // function to setup the cells

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "channelCell", for: indexPath) as? ChannelCell {
I double check the reusable identifier is OK

            let channel = MessageService.instance.channels[indexPath.row]
            cell.configureCell(channel: channel)
            return cell
        } else {
            return UITableViewCell()
        }
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if MessageService.instance.channels.count == 0 {
            tableView.setEmptyView(title: "Message!", message: "You don´t have any channel, create a new one")
        }
        return MessageService.instance.channels.count
    }
}

this is the view I want to show when I click on the addChannel function view to present

and this is the debug area debug area

dgoldfeder
  • 29
  • 5
  • [Don't repost questions](https://stackoverflow.com/questions/60708351/uitableview-stop-working-after-i-tried-to-show-an-uiview). Did you read the information in the duplicate? If the code crashes at this point then the outlet is not connected. – vadian Mar 16 '20 at 18:45
  • The outlet it is connected, before I posted my first question I already tried the info in the link you gave me, I tried not to post any question until I do an extensive reading of other posts. Sorry I didn't want to annoy anyone. – dgoldfeder Mar 17 '20 at 03:03
  • where did you register `tableView cell`? – Habin Lama Mar 17 '20 at 05:52
  • @Vadian I did what you told me and no more error but it didn´t solve my issue. I think I did not explain myself correctly about this issue, I said I want to show a new UIView when I click on a button. This UIView is a XIB file, I do no know if this new info helps. – dgoldfeder Mar 17 '20 at 23:21
  • @HabinLama you mean where I declare the cell? I did it with the help of the Main.storyboard I put the tableview and inside this one the table view cell. – dgoldfeder Mar 17 '20 at 23:25

1 Answers1

0

You are making a very common mistake. The line

let addChannel = ChannelVC()

creates a new instance of the controller which is not the instance in the storyboard. Therefore the outlets are not connected and the code crashes.

Replace it with (adjust the identifier accordingly)

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let addChannel = storyboard.instantiateViewController(withIdentifier: "ChannelVC") as! ChannelVC

or create a segue.

vadian
  • 274,689
  • 30
  • 353
  • 361