Search code examples
xcodeuitableviewprotocolsviewcontroller

"type" viewController does not conform to protocol "UITableViewDataSource"


I keep getting this error for some reason.

"type" viewController does not conform to protocol "UITableViewDataSource"

I know that this has been covered a million times and there are even videos explaining why this problem occurs, but for some reason I can't fix it and can't figure out exactly what it is that I have done wrong.

Here is my code:

//
//  ViewController.swift
//  ChatApp
//
//  Created by K on 17/03/2015.
//  Copyright (c) 2015 Krazy88 All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {

    @IBOutlet weak var dockViewHeightConstraint: NSLayoutConstraint!
    @IBOutlet weak var sendButton: UIButton!
    @IBOutlet weak var messageTextField: UITextField!
    @IBOutlet weak var messageTableView: UITableView!

    var messagesArray:[String] = [String]()
    var delegate: UITableViewDataSource? = nil

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        self.messageTableView.delegate = self
        self.messageTableView.dataSource = self

        // Set self as the delegate for the textfield
        self.messageTextField.delegate = self

        //Add a tap gesture recognizer to the tableview
        let tapGesture:UITapGestureRecognizer = UITapGestureRecognizer(target:self, action: "tableViewTapped")
        self.messageTableView.addGestureRecognizer(tapGesture)

        // Retrieve messages from Parse
        self.retreiveMessages()
    }

    override func didReceiveMemoryWarning(){
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func sendButtonTapped(sender: UIButton) {

        // Send button is tapped

        // Call the end editing method for the text field
        self.messageTextField.endEditing(true)

        //Disable the send button and textfield
        self.messageTextField.enabled = false
        self.sendButton.enabled = false

        // Create a PFObject
        var newMessageObject:PFObject = PFObject(className: "Message")

        // Set the Text key to the text of the messageTextField
        newMessageObject["Text"] = self.messageTextField.text

        // Save the PFObject
        newMessageObject.saveInBackgroundWithBlock { (success:Bool, error:NSError!) -> Void in

            if (success == true) {
                //Message has been saved!
                // TODO: Retrieve the latest messages and reload the table
                NSLog("Message saved successfully.")
            }
            else {
                // Something bad happened.
                NSLog(error.description)
            }

            // Enable the textfield and send button
            self.sendButton.enabled = true
            self.messageTextField.enabled = true
            self.messageTextField.text = ""

        }


    }

    func retreiveMessages() {

        // Create a new PFQuery
        var query:PFQuery = PFQuery(className: "Message")

        // Call findobjectsinbackground
        query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in

            // clear the messageArray
            self.messagesArray = [String]()

            // Loop through the objects array
            for messageObject in objects {

                // Retrieve the Text column of each PFObject
                let messageText:String? = (messageObject as PFObject)["Text"] as? String

                // Assign it into our messagesArray
                if messageText != nil {
                    self.messagesArray.append(messageText!)
                }
            }

            // Reload the tableview
            self.messageTableView.reloadData()

            // Reload the tableview
        }

        func tableViewTapped() {

            // Force the textfield to end editing
            self.messageTextField.endEditing(true)

        }

        // MARK: Textfield Delegate Methods

        func textFieldDidBeginEditing(textField: UITextField) {

            // Perform an animation to grow the dockview
            self.view.layoutIfNeeded()
            UIView.animateWithDuration(0.5, animations: {

                self.dockViewHeightConstraint.constant = 350
                self.view.layoutIfNeeded()

                } , completion: nil)

        }

        func textFieldDidEndEditing(textField:UITextField) {

            // Perform an animation to grow the dockview
            self.view.layoutIfNeeded()
            UIView.animateWithDuration(0.5, animations: {

                self.dockViewHeightConstraint.constant = 60
                self.view.layoutIfNeeded()

                }, completion: nil)

        }


        // MARK: TableView Delegate Methods

        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

            // Create a table cell
            let cell = self.messageTableView.dequeueReusableCellWithIdentifier("MessageCell") as UITableViewCell

            // Customize the cell
            cell.textLabel.text = self.messagesArray[indexPath.row]

            //Return the cell
            return cell
        }

            func TableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

                return messagesArray.count
            }


        }

    }

Any helps tips or suggestion will be much appreciated as I have tried everything!

thanks for reading

Kurando


Solution

  • Your UITableViewDataSource @required delegates are inside retreiveMessages(). Fix the position of that second last bracket..!!

    Here is your correct code :

    import Foundation
    import UIKit
    
    class ViewController : UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate {
    
    @IBOutlet weak var dockViewHeightConstraint: NSLayoutConstraint!
    @IBOutlet weak var sendButton: UIButton!
    @IBOutlet weak var messageTextField: UITextField!
    @IBOutlet weak var messageTableView: UITableView!
    
    var messagesArray:[String] = [String]()
    var delegate: UITableViewDataSource? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Do any additional setup after loading the view, typically from a nib.
    
        messageTableView.delegate = self
        messageTableView.dataSource = self
    
        // Set self as the delegate for the textfield
        self.messageTextField.delegate = self
    
        //Add a tap gesture recognizer to the tableview
        let tapGesture:UITapGestureRecognizer = UITapGestureRecognizer(target:self, action: "tableViewTapped")
        self.messageTableView.addGestureRecognizer(tapGesture)
    
        // Retrieve messages from Parse
        self.retreiveMessages()
    }
    
    override func didReceiveMemoryWarning(){
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    @IBAction func sendButtonTapped(sender: UIButton) {
    
        // Send button is tapped
    
        // Call the end editing method for the text field
        self.messageTextField.endEditing(true)
    
        //Disable the send button and textfield
        self.messageTextField.enabled = false
        self.sendButton.enabled = false
    
        // Create a PFObject
        var newMessageObject:PFObject = PFObject(className: "Message")
    
        // Set the Text key to the text of the messageTextField
        newMessageObject["Text"] = self.messageTextField.text
    
        // Save the PFObject
        newMessageObject.saveInBackgroundWithBlock { (success:Bool, error:NSError!) -> Void in
    
            if (success == true) {
                //Message has been saved!
                // TODO: Retrieve the latest messages and reload the table
                NSLog("Message saved successfully.")
            }
            else {
                // Something bad happened.
                NSLog(error.description)
            }
    
            // Enable the textfield and send button
            self.sendButton.enabled = true
            self.messageTextField.enabled = true
            self.messageTextField.text = ""
    
        }
    }
    
    func retreiveMessages() {
    
        // Create a new PFQuery
        var query:PFQuery = PFQuery(className: "Message")
    
        // Call findobjectsinbackground
        query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in
    
            // clear the messageArray
            self.messagesArray = [String]()
    
            // Loop through the objects array
            for messageObject in objects {
    
                // Retrieve the Text column of each PFObject
                let messageText:String? = (messageObject as PFObject)["Text"] as? String
    
                // Assign it into our messagesArray
                if messageText != nil {
                    self.messagesArray.append(messageText!)
                }
            }
    
            // Reload the tableview
            self.messageTableView.reloadData()
    
            // Reload the tableview
        }
    }
    
        func tableViewTapped() {
    
            // Force the textfield to end editing
            self.messageTextField.endEditing(true)
    
        }
    
        // MARK: Textfield Delegate Methods
    
        func textFieldDidBeginEditing(textField: UITextField) {
    
            // Perform an animation to grow the dockview
            self.view.layoutIfNeeded()
            UIView.animateWithDuration(0.5, animations: {
    
                self.dockViewHeightConstraint.constant = 350
                self.view.layoutIfNeeded()
    
                } , completion: nil)
    
        }
    
        func textFieldDidEndEditing(textField:UITextField) {
    
            // Perform an animation to grow the dockview
            self.view.layoutIfNeeded()
            UIView.animateWithDuration(0.5, animations: {
    
                self.dockViewHeightConstraint.constant = 60
                self.view.layoutIfNeeded()
    
                }, completion: nil)
    
        }
    
    
        // MARK: TableView Delegate Methods
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return messagesArray.count
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
        // Create a table cell
        let cell = self.messageTableView.dequeueReusableCellWithIdentifier("MessageCell") as UITableViewCell
    
        // Customize the cell
        cell.textLabel?.text = self.messagesArray[indexPath.row]
    
        //Return the cell
        return cell
    }
    
    }
    

    Copy from here.

    And always make sure to call numberOfRowsInSection before cellForRowAtIndexPath.