Reputation: 2466
So here is the structure of the TableView: There is a main UITableView, and inside each UITableViewCell there is another UITableview
Each of the UITableViewCells have been designed as Custom Views and have been added by loading it from the Nib in the cellForRowAtIndexPath function.
What I want to do is for any option selected in the inner Table Views I want to get the index path of the cell that the Table View is embeded in.
I tried to follow the delegate approach mentioned by Paulw11 here: swift: how to get the indexpath.row when a button in a cell is tapped?: StackOverflow
Note: The method suggested by Paulw11 works perfectly
Code(TableVC):
class TableVC: UITableViewController, QuestionCellDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 5
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 220.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("QuestionCell", owner: self, options: nil)?.first as! QuestionCell
cell.delegate = self
return cell
}
func sendCellInfo(cell: UITableViewCell) {
print(cell)
let indexPathForQuestion = tableView.indexPath(for: cell)
print(indexPathForQuestion)
}}
Code(QuestionCell):
protocol QuestionCellDelegate: class {
func sendCellInfo(cell: UITableViewCell)
}
class QuestionCell: UITableViewCell, UITableViewDelegate, UITableViewDataSource{
@IBOutlet weak var optionsTableview: UITableView!
var delegate: QuestionCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.optionsTableview.delegate = self
self.optionsTableview.dataSource = self
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("OptionsCell", owner: self, options: nil)?.first as! OptionsCell
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = optionsTableview.cellForRow(at: indexPath)
print("selectedCell")
self.delegate?.sendCellInfo(cell: selectedCell!)
}}
Code(OptionsCell):
class OptionsCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}}
Note: The current O/P is nil
Note: Code changed as per commented by pbasdf, realised the mistake
Upvotes: 1
Views: 313
Reputation: 2114
The following answer is added @Supratik Majumdar request for the logic which I said.
Supratik try using the following code, I hope you will get your need done.
//Initialize your question or answer in viewDidLoad or where ever you like to as shown below
self.questionArray = ["Question1", "Question2"]
self.optionArray = [["Option 1", "Option 2", "Option 3", "Option 4"], ["Option 1", "Option 2", "Option 3", "Option 4"]]
//Make us of the following tableview delegate & datasource code
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.questionArray.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.OptionArray[section].count
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {
return self.questionArray[section]
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
let currentOptionArray = self.questionArray[section]
let currentOption = currentOptionArray[indexPath.row]
cell.textLabel.text = currentOption
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedIndex = indexPath
let selectedQuestionIndex = indexPath.section
let selectedOptionIndex = indexPath.row
//Make use of the data you need in the above values
}
Upvotes: 0
Reputation: 2466
Found the solution due to pbasdf comment:
Delegate Function in TableVC:
func sendCellInfo(cell: UITableViewCell) {
/*** Take the cell passed and convert to a CGPoint wrt to TableView ***/
let cellPosition: CGPoint = cell.convert(cell.bounds.origin, to: self.tableView)
/*** wrt to CGPoint find index on current TableView ***/
/*** Returns as Section,Cell ***/
let indexPathForSelectedCell = (tableView.indexPathForRow(at: cellPosition)?.row)
print(indexPathForSelectedCell)
}
Upvotes: 1
Reputation: 374
Use this:
tableView.cellForRowAtIndexPath(YourIndexPath) as! OptionCell
You can do your own indexPath as global variable and filing it on didSelectRow method
YourIndexPath = indexPath
Upvotes: 0