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....
}
}
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.