I'm Creating an demo on Expandeble Tableview, Expanding is working Fine... But facing issue while didselect row is tapped

48 views Asked by At

Expanding and Collapsing is working fine tableview, Only facing issue while didselect row is tapped, I'm getting same index evry time after selecting a row. I'm getting the same out put, I want to pass the data to next view but output isn't working properly.

Here's My Details...

My OutPut enter image description here My Model

struct ItemList {
var name: String
var items: [String]
var collapsed: Bool

init(name: String, items: [String], collapsed: Bool = false) {
     self.name = name
     self.items = items
     self.collapsed = collapsed
    }
}

My ViewController Class

class ViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!
var sections = [ItemList]()
var items: [ItemList] = [
 ItemList(name: "Mac", items: ["MacBook", "MacBook Air"]),
 ItemList(name: "iPad", items: ["iPad Pro", "iPad Air 2"]),
 ItemList(name: "iPhone", items: ["iPhone 7", "iPhone 6"])
]
override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
}
}

TableView Extension

extension ViewController:UITableViewDelegate,UITableViewDataSource{

 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}

  func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerHeading = UILabel(frame: CGRect(x: 5, y: 10, width: self.view.frame.width, height: 40))
let imageView = UIImageView(frame: CGRect(x: self.view.frame.width - 30, y: 20, width: 20, height: 20))
if items[section].collapsed{
    imageView.image = UIImage(named: "collapse")
}else{
    imageView.image = UIImage(named: "expand")
}
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 60))
let tapGuesture = UITapGestureRecognizer(target: self, action: #selector(headerViewTapped))
tapGuesture.numberOfTapsRequired = 1
headerView.addGestureRecognizer(tapGuesture)
headerView.backgroundColor = UIColor.red
headerView.tag = section
headerHeading.text = items[section].name
headerHeading.textColor = .white
headerView.addSubview(headerHeading)
headerView.addSubview(imageView)
return headerView
}

func numberOfSections(in tableView: UITableView) -> Int {
  return items.count
 }

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
{
let itms = items[section]
return !itms.collapsed ? 0 : itms.items.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> 
  UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = items[indexPath.section].items[indexPath.row]
return cell
 }

@objc func headerViewTapped(tapped:UITapGestureRecognizer){
print(tapped.view?.tag)
if items[tapped.view!.tag].collapsed == true{
    items[tapped.view!.tag].collapsed = false
}else{
    items[tapped.view!.tag].collapsed = true
}
if let imView = tapped.view?.subviews[1] as? UIImageView{
    if imView.isKind(of: UIImageView.self){
        if items[tapped.view!.tag].collapsed{
            imView.image = UIImage(named: "collapsed")
        }else{
            imView.image = UIImage(named: "expand")
        }
    }
  }
   tableView.reloadData()
 }

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let row = items[indexPath.row]
    print("IndexPath :- \(row.name)")
}
}
1

There are 1 answers

0
DonMag On BEST ANSWER

If you look at the way you are setting the text in your cells in cellForRowAt:

cell.textLabel?.text = items[indexPath.section].items[indexPath.row]

You are saying:

  • get the ItemList object for indexPath.section from items array
  • get the String from that object's items array of this indexPath.row

However, in your didSelectRowAt:

let row = items[indexPath.row]
print("IndexPath :- \(row.name)")

You are saying:

  • get the ItemList object for indexPath.row from items array
  • print the .name property of that object

So, change your didSelectRowAt code to match your cellForRowAt logic:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
    let selectedString = items[indexPath.section].items[indexPath.row]
    print("IndexPath :- \(selectedString)")

    // or, for a little more clarity
    let sectionObject = items[indexPath.section]
    let rowItem = sectionObject.items[indexPath.row]
    
    print("IndexPath :- \(indexPath)  //  Section :- \(sectionObject.name)  //  Item :- \(rowItem)")
    
}