Sillenxy
Sillenxy

Reputation: 130

How to change tableView numberOfRows and Cells based on which button is clicked in Swift iOS

I have two buttons in my user's profile page, one for the saved shop items and one for his reviews.

I want when the user clicks the saved button it would load his saved shop's items in the table view and when he clicks the reviews button it would load his reviews.

I'm struggling on how to figure out how to do this

Any help, please?

here is my code:

@IBOutlet weak var reviewsBtn: UIButton!
@IBOutlet weak var saveBtntab: UIButton! 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if(reviewsBtn.isSelected == true){
            print("review selected")
            return reviews.count
        }
        if(saveBtntab.isSelected == true){
            print("saved selected")
            return shops.count
        }
          return shops.count
      }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

 let cell = tableView.dequeueReusableCell(withIdentifier: "cellFave", for: indexPath) as! FaveTableViewCell
        let shops = self.shops[indexPath.row]
        let reviews = self.reviews[indexPath.row]
// i want to do the same idea for the number of rows here.
}

  @IBAction func reviewsTapped(_ sender: Any) {
        reviewsBtn.isSelected = true
        reviewsBtn.isEnabled = true
        faveBtntab.isEnabled = false
        faveBtntab.isSelected = false
    }
    
    @IBAction func savedTapped(_ sender: Any) {
        faveBtntab.isSelected = true
        faveBtntab.isEnabled = true
        reviewsBtn.isEnabled = false
        reviewsBtn.isSelected = false
      
    }

Upvotes: 0

Views: 266

Answers (2)

vadian
vadian

Reputation: 285069

First of all if there are only two states you can simplify numberOfRows

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return reviewsBtn.isSelected ? reviews.count : shops.count
}

In cellForRow do the same thing, display the items depending on reviewsBtn.isSelected

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

     let cell = tableView.dequeueReusableCell(withIdentifier: "cellFave", for: indexPath) as! FaveTableViewCell
     if reviewsBtn.isSelected {
          let reviews = self.reviews[indexPath.row]
          // assign review values to the UI
     } else {
          let shops = self.shops[indexPath.row]
          // assign shop values to the UI
     }
}

And don't forget to call reloadData when the state has changed.

Upvotes: 1

Tarun Tyagi
Tarun Tyagi

Reputation: 10102

You can create two different dataSource instances for clarity and separation like following -

class ShopsDataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
    var shops: [Shop] = []
    var onShopSelected: ((_ shop: Shop) -> Void)?

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ShopTableViewCell", for: indexPath) as! ShopTableViewCell
        
        let shop = self.shops[indexPath.row]
        cell.populateDetails(shop: shop)
        
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.onShopSelected?(shops[indexPath.row])
    }
}

class ReviewsDataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
    var reviews: [Review] = []
    var onReviewSelected: ((_ review: Review) -> Void)?

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ReviewTableViewCell", for: indexPath) as! ReviewTableViewCell
        
        let review = self.reviews[indexPath.row]
        cell.populateDetails(review: review)
        
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.onReviewSelected?(reviews[indexPath.row])
    }
}

class ViewController: UIViewController {
    let shopsDataSource = ShopsDataSource()
    let reviewsDataSource = ReviewsDataSource()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(ShopTableViewCell.self, forCellReuseIdentifier: "ShopTableViewCell")
        tableView.register(ReviewTableViewCell.self, forCellReuseIdentifier: "ReviewTableViewCell")
        
        shopsDataSource.onShopSelected = { [weak self] (shop) in
            self?.showDetailsScreen(shop: shop)
        }
        
        reviewsDataSource.onReviewSelected = { [weak self] (review) in
            self?.showDetailsScreen(review: review)
        }
    }

    @IBAction func shopsTapped(_ sender: Any) {
        tableView.dataSource = shopsDataSource
        tableView.delegate = shopsDataSource
        tableView.reloadData()
    }

    @IBAction func addNewShop(_ sender: Any) {
        /// ask user about shop details and add them here
        shopsDataSource.shops.append(Shop())
        tableView.reloadData()
    }
    
    func showDetailsScreen(shop: Shop) {
        /// Go to shop details screen
    }
    
    @IBAction func reviewsTapped(_ sender: Any) {
        tableView.dataSource = reviewsDataSource
        tableView.delegate = reviewsDataSource
        tableView.reloadData()
    }

    @IBAction func addNewReview(_ sender: Any) {
        /// ask user about review details and add them here
        reviewsDataSource.reviews.append(Review())
        tableView.reloadData()
    }

    func showDetailsScreen(review: Review) {
        /// Go to review details screen
    }
}

Upvotes: 0

Related Questions