Home > Blockchain >  Cannot assign value of type 'ViewController' to type 'AddContactDelegate?'
Cannot assign value of type 'ViewController' to type 'AddContactDelegate?'

Time:05-24

import UIKit

struct Contact  {
    var fullname: String
    var contactNumber: String
}

class ViewController: UITableViewController {

    var contacts = [Contact]()
    @IBOutlet var tableview: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    @IBAction func handleAdd(_ sender: Any) {
        let controller = AddContacts()
        controller.delegate = self
        self.present(UINavigationController(rootViewController: controller), animated: true, completion: nil)
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = contacts[indexPath.row].fullname
        cell.detailTextLabel?.text = contacts[indexPath.row].contactNumber
        return cell

    }

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


import UIKit

protocol AddContactDelegate {
    func addContact(contact: Contact)
}

class AddContacts: UIViewController {

    var delegate: AddContactDelegate?
    
    @IBOutlet weak var ContactTextField: UITextField!
    @IBOutlet weak var nameTextField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    
    @IBAction func save(_ sender: Any) {
        guard let fullname = nameTextField.text, nameTextField.hasText else {
            print("handle error here")
            return
        }
        
        guard let contactNumber = ContactTextField.text , ContactTextField.hasText else {
            print("enter contact error here")
            return
        }
        let contact  = Contact(fullname: fullname, contactNumber: contactNumber)
        print(contact.fullname)
        print(contact.contactNumber)
        delegate?.addContact(contact: contact)
    }
    
}

in viewController: UITableViewController file it shows error like Cannot assign value of type 'ViewController' to type 'AddContactDelegate?' what should do i do to solve these error

CodePudding user response:

You must add protocol function in ViewController

 class ViewController: UITableViewController , AddContactDelegate{
    func addContact(contact: Contact) {
    
     }
 }

In addition , object from AddContacts with using let controller = AddContacts() is not pointing the viewcontroller that you declared in storyboard . Change it

let controller = self.storyboard.instantiateViewControllerWithIdentifier("AddContactsId") as AddContacts

CodePudding user response:

import UIKit

struct Contact  {
    var fullname: String
    var contactNumber: String
}

class ViewController: UITableViewController {

    var contacts = [Contact]()
    @IBOutlet var tableview: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    @IBAction func handleAdd(_ sender: Any) {
        let controller = AddContacts()
        controller.delegate = self
        self.present(UINavigationController(rootViewController: controller), animated: true, completion: nil)
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = contacts[indexPath.row].fullname
        cell.detailTextLabel?.text = contacts[indexPath.row].contactNumber
        return cell

    }

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

// add this

extension ViewController: AddContactDelegate {
      func addContact(contact: Contact) {
           contacts.append(contact)
           tableView.reloadData()
       }
}

// thats it

import UIKit

protocol AddContactDelegate:AnyObject {
    func addContact(contact: Contact)
}

class AddContacts: UIViewController {

    weak var delegate: AddContactDelegate?
    
    @IBOutlet weak var ContactTextField: UITextField!
    @IBOutlet weak var nameTextField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    
    @IBAction func save(_ sender: Any) {
        guard let fullname = nameTextField.text, nameTextField.hasText else {
            print("handle error here")
            return
        }
        
        guard let contactNumber = ContactTextField.text , ContactTextField.hasText else {
            print("enter contact error here")
            return
        }
        let contact  = Contact(fullname: fullname, contactNumber: contactNumber)
        print(contact.fullname)
        print(contact.contactNumber)
        delegate?.addContact(contact: contact)
    }
    
}

CodePudding user response:

You must implement the protocol inside the ViewController.

Why xcode shows you the error is:

protocol ViewDelegate: AnyObject {
   func didDoSomething()
}

// Which means - reference with name delegate can store objects that conform to the protocol ViewDelegate
var delegate: ViewDelegate

If you did not conform the object you are trying to store to this reference with the desired protocol, you will not be able to store that object to that reference.

You can look at protocols like contracts, if the protocol is implemented in a specific class, the class must implement the declared methods inside the protocols.

Simply implementing this protocol to your ViewController and adding the method declared in the protocol (contract) will make you achieve what you want.

class MyViewController: ViewDelegate {
   func didDoSomething() {
       //TODO: Logic for this method
   }
}

//Will not give compile errors
let delegate: ViewDelegate = MyViewController()

Just for additional info, you can always implement a delegate in this way

class MyViewController {
//properties
}

//MARK: - ViewDelegate implementation
extension MyViewController: ViewDelegate {
   func didDoSomething() {
      //TODO: logic
   }
}

Hope it helps.

  • Related