简体   繁体   中英

Add same UITableView to different ViewControllers

In my app I have same UI component that should be presented in different ViewControllers. This component looks like list of buttons, tapping on each of this button should push VievController with some params - I decided to use UITableView for it.

Lets say I have ViewControllers: VC1,VC2,VC3 where this UITableView should be presented. Number of cells that should be presented in each ViewController are stored in array called buttons .

在此处输入图片说明

struct Button {
    var title : String
    var param : Int
}

class VC1 : UIViewController {
     var buttons = [Button]()
}

Right now I am creating this tableView in every ViewController like

class VC1 : UIViewController, UITableViewDelegate, UITableViewDataSource {
     var buttons = [Button]()

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

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     ....
     return btnCell
     }

      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
           performSegue....
      }
}
  • What is the best way to declare this TableView? Where should I put all UITableView delegation methods?
  • Should I create separate UIView subclass for this table with custom XIB file
  • It it nice place to create some protocol canShowButtons? And if so - what vars and methods are needed.

You can put all your UI elements in xib and handle tableView delegate in that xib class. If you want to communicate between xib and VC1 you can write a protocol. Or the second approach is really similar, you can create a viewController (lets name it UIelemntsVC ) that has all UI elements (tableView, buttons, etc) and load it in your VC1, VC2, VC3, etc.

In UIelementsVC class you can control it's size like this

self.view.frame = CGRect(x: 0, y: UIScreen.main.bounds.height, width: self.view.frame.width, height: self.view.frame.height*2)

If you want to use Auto Layout, than you should place a UIView in your VC1 and add UIelementsVC subview to it.

You can load a custom ViewController like this:

let customVC = UIelementsVC()
customVC.customDelegate = self // Only if you have a custom protocol
customVC.numberOfButtons = 5 // You can edit vars in customVC like this

self.addChildViewController(customVC)
self.view.addSubview(customVC)
customVC(toParentViewController: self)

Just make this code you called VC1 like that:

class ButtonTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    ...

    // The better is not to make the data as UIButton s,
    //    but as data (Strings/Int/Structs/etc...), for testability
    //    and flexibility.

    var dataSource = (() -> (UIButton))? {
        didSet {
            populateData()
        }
    }

    func registerTheCellsFromXIB() {
        // Here try to use register(_:forCellReuseIdentifier:)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        registerTheCellsFromXIB()
        populateData()
    }

    func populateData() {
        buttons = dataSource?()
    }
    ...

}

Then you could make ONE XIB, for all of them. If you want the cell in one is different than the other, make more than XIB for the different types of cells, then put a settable closure that can registerTheCellsFromXIB() instead of just a plain function (use the same technique made for populateDate

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM