Home > Software design >  Custom Segment Controlled UITableView
Custom Segment Controlled UITableView

Time:10-17

I'm trying to create a UISegmentedControl, in which, when a segment is selected, it changes the table view and the cells change accordingly. But unfortunately an empty table appears, and when you select the segment again, the application crashes. Please help me find and fix the bugs.

class PriceViewController: UIViewController {

var priceDictionary: [String : String] = [
    "мини-тату": "2000-4000р",
    "перманент бровей" : "4500р",
    "коррекция" : "50% от тату",
    "коррекция пм бровей" : "2500"
]

var stockDictionary: [String : String] = [
    "Скидка имениннику 20%":"Скидка действительна 3 дня до дня рождения и 3 дня после, при предъявлении оригинала документа, удостоверяющего личность. Скидка не распространяется на другие акции.",
    "Две и более мини-тату со скидкой 30%": "Скидка предоставляется при оформлении записи на 2 и более мини-тату за один сейчас.",
    "Скидка для подружек": "Приведи подругу и получу скидку на следующую татуировку/перманент/коррекцию 15%."
]

@IBOutlet var sideMenuBtn: UIBarButtonItem!
@IBOutlet weak var segmentedController: UISegmentedControl!
@IBOutlet weak var tableView: UITableView! 

override func viewDidLoad() {
    super.viewDidLoad()
    
    navigationController?.navigationBar.tintColor = .white
    self.sideMenuBtn.target = revealViewController()
    self.sideMenuBtn.action = #selector(self.revealViewController()?.revealSideMenu)
    
    tableView.delegate = self
    tableView.dataSource = self
    
    switch segmentedController.selectedSegmentIndex {
    case 0:
        tableView.register(UINib(nibName: PriceCell.identifier, bundle: nil), forCellReuseIdentifier: PriceCell.identifier)
        tableView.reloadData()
    case 1 :
        tableView.register(UINib(nibName: StockCell.identifier, bundle: nil), forCellReuseIdentifier: StockCell.identifier)
        tableView.reloadData()
    default:
        break
    }
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.revealViewController()?.gestureEnabled = false
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.revealViewController()?.gestureEnabled = true
}

func loadCellPrice(indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: PriceCell.identifier, for: indexPath) as! PriceCell
    cell.nameOfServiceLabel?.text = Array(priceDictionary.keys)[indexPath.row]
    cell.priceLabel?.text = Array(priceDictionary.values)[indexPath.row]
    return cell
}

func loadCellStock(indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: StockCell.identifier, for: indexPath) as! StockCell
    cell.nameStock?.text = Array(stockDictionary.keys)[indexPath.row]
    cell.descriptionStock?.text = Array(stockDictionary.values)[indexPath.row]
    return cell
}

}

extension PriceViewController: UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch segmentedController.selectedSegmentIndex {
    case 0:
        return priceDictionary.count
    case 1 :
        return stockDictionary.count
    default:
        return 0
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    switch segmentedController.selectedSegmentIndex {
    case 0:
        return loadCellPrice(indexPath: indexPath)
    case 1 :
        return loadCellStock(indexPath: indexPath)
    default:
        return UITableViewCell()
    }
}

}

CodePudding user response:

You have not implemented the valueChanged method for your code to work when the segment controller is toggled.

Please add this code to your viewController and connect the @IBAction from the storyboard. It should work:

@IBAction func segmentValueChanged(_ sender: UISegmentedControl) {
     tableView.reloadData()
}

CodePudding user response:

You should register both tableView cells before using it.

Along with the @Cedan answer, change the below implementation in your viewDidLoad method

 switch segmentedController.selectedSegmentIndex {
case 0:
    tableView.register(UINib(nibName: PriceCell.identifier, bundle: nil), forCellReuseIdentifier: PriceCell.identifier)
    tableView.reloadData()
case 1 :
    tableView.register(UINib(nibName: StockCell.identifier, bundle: nil), forCellReuseIdentifier: StockCell.identifier)
    tableView.reloadData()
default:
    break
}

To

tableView.register(UINib(nibName: PriceCell.identifier, bundle: nil), forCellReuseIdentifier: PriceCell.identifier)
tableView.register(UINib(nibName: StockCell.identifier, bundle: nil), forCellReuseIdentifier: StockCell.identifier)
  • Related