0

Overview
I'm trying to better understand how extensions work.
In my app I have a ViewController. There I put a view of another class. In this custom class I put a bunch of buttons and a table view. I want them to display some text inside of my tableView whenever I press them.
The problem is that I want to edit some of the table view functions in order to better adjust it to my ViewController.

What I know
All I know is based on the apple documentation

What I'm doing
What I'm trying to do, I should say, is to add functionality to a custom view's function after adding an object which is of the type of my custom class to the ViewController.

This is my custom class:

class CustomClass: UIView{
@IBOutlet weak var abtn: UIButton!
@IBOutlet weak var table: UITableView!

 func setupTable(){ 
 table.delegate = self
        table.dataSource = self
        
        table.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
        table.backgroundColor = UIColor.black.withAlphaComponent(0.1)
}
}
extension CustomClass: UITableViewDelegate, UITableViewDataSource{
 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = table.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
        
        return cell
    }
 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      print("I want to add stuff here too")
        
    }
    //And more stuff that is not useful rn
}

Inside of the ViewController class I have declared a variable of type CustomClass.

@IBOutlet weak var custom: CustomClass!
In my viewDidLoad I call :
custom.setupTable()

What I need to do is creating an extension to edit the tableview that belongs to custom (the variable of type CustomClass that is inside of my ViewController).

I have no clue on how to do that.

I know how to work with extension to expand my code's functionality but I don't know how to use them to edit these other functions.

Question
How do I edit the tableview functions that belong to custom?
Ie. how would I be able to change the number of rows or to change the cell's layout from the class I call the object in?

I hope I was clear enough...

crost
  • 165
  • 1
  • 13

1 Answers1

1

For this specific example...

Add a property to your CustomClass:

class CustomClass: UIView {
    
    // this may be changed by the "calling class"
    var numRows: Int = 10
    
    @IBOutlet weak var abtn: UIButton!
    @IBOutlet weak var table: UITableView!
    
    func setupTable(){
        table.delegate = self
        table.dataSource = self
        
        table.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
        table.backgroundColor = UIColor.black.withAlphaComponent(0.1)
    }
}

In your extension, use that property:

extension CustomClass: UITableViewDelegate, UITableViewDataSource{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // don't make this a hard-coded number
        //return 10
        return numRows
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = table.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
        
        return cell
    }
    //And more stuff that is not useful rn
}

Then, in your "calling class", you can change that property:

class ExampleViewController: UIViewController {
    
    let myView = CustomClass()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        view.addSubview(myView)
        // constraints, etc
        
        // change the number of rows in the table in myView
        myView.numRows = 20
    }
    
}

More likely, though, you would be doing something like setting / changing the data for the table in your custom class.

Here's an example, along with showing how to use a closure to "call back" to the calling class / controller:

class CustomClass: UIView {
    
    // this may be changed by the "calling class"
    var theData: [String] = []
    
    // closure to "call back" to the controller
    var callback: ((IndexPath) -> ())?
    
    @IBOutlet weak var abtn: UIButton!
    @IBOutlet weak var table: UITableView!
    
    func setupTable(){
        table.delegate = self
        table.dataSource = self
        
        table.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
        table.backgroundColor = UIColor.black.withAlphaComponent(0.1)
    }
}
extension CustomClass: UITableViewDelegate, UITableViewDataSource{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return theData.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = table.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
        cell.textLabel?.text = theData[indexPath.row]
        return cell
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // tell the controller the cell was selected
        callback?(indexPath)
    }
}

class ExampleViewController: UIViewController {
    
    let myView = CustomClass()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        view.addSubview(myView)
        // constraints, etc
        
        // set the data in CustomClass
        myView.theData = [
            "First row",
            "Second row",
            "Third",
            "Fourth",
            "etc..."
        ]
        
        myView.callback = { indexPath in
            print("CustomClass myView told me \(indexPath) was selected!")
            // do what you want
        }
    }
    
}
DonMag
  • 69,424
  • 5
  • 50
  • 86
  • Excellent explanation, thank you a lot! I have another question before I accept the answer: what if I want to add a function to my table view so I need to edit the didSelectRowAt function? how would you suggest i'd do that? – crost Sep 22 '20 at 19:28
  • @crost - you'll need to provide a better detailed question than *"I need to edit the didSelectRowAt function"* ... that, by itself, doesn't make any sense. – DonMag Sep 22 '20 at 19:37
  • I edited the extension in my question, the last function there is the one i'd like to edit as well. What I mean is that i'd like to know how i should act if I wanted, for example, add somehing in that function as well from the other view controller. let me know if I was clear – crost Sep 22 '20 at 19:48
  • @crost - you need to read up on protocol/delegate pattern and closures. I edited my answer with an example of using a closure. – DonMag Sep 22 '20 at 20:31
  • You were very kind and clear, thank you for your time and your help. – crost Sep 22 '20 at 20:51