Reputation: 21
We are designing an app and we have one table view controller and one view controller. In my tab view controller it has buttons in every cell and we drag it to make it a connection with the view controller cell. If we clicked buttons in different cells we want to update the data in our view controller from coredata.(each button goes to different person information) But the problem is we can not access the information about cell's from view controller class. We found some examples in here but we could not do it.
//table view controller class
var charArray = ["a","b","c"]
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
let myCharacter = charArray[indexPath.row]
cell.textLabel?.font = UIFont(name: "HoeflerText-Italic", size: 27.0)
cell.textLabel?.text = myCharacter
return cell
}
//view controller class
override func viewDidLoad() {
super.viewDidLoad()
charText.isEditable = false
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext// This one is created to work with Managed Object
let entity = NSEntityDescription.entity(forEntityName: "CHARACTER",in: managedContext)!
if let a = CI.tableView.cellForRow(at: IndexPath.init(row: i, section: i)),a.textLabel?.text == "Iron Man"{
imageChar.image = UIImage(named: "Iron_Man")
btn1.setTitle("Iron Man ", for: .normal)
btn1.showsTouchWhenHighlighted = true
btn2.setTitle("Iron Man 2", for: .normal)
btn2.showsTouchWhenHighlighted = true
btn3.setTitle("Iron Man 3", for: .normal)
btn3.showsTouchWhenHighlighted = true
let person = NSManagedObject(entity: entity,insertInto: managedContext)
person.setValue(CHS[0].species , forKeyPath: "species")
person.setValue(CHS[0].name , forKeyPath: "title")
person.setValue(CHS[0].gender, forKeyPath: "gender")
person.setValue(CHS[0].textInfo, forKey: "information")
person.setValue(CHS[0].age, forKey: "age")
do {// Save into our app's dedicated disk area
try managedContext.save()
people.append(person)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
// print(people.first as Any)
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "CHARACTER")
do{
let request = try managedContext.fetch(fetchRequest)
for data in request{
labelName.text = data.value(forKey: "title") as? String
labelSpecies.text = data.value(forKey: "species") as? String
labelGender.text = data.value(forKey: "gender") as? String
charText.text = data.value(forKey: "information") as? String
labelAge.text = data.value(forKey: "age") as? String
}
}
catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
//Another option --------
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let StoryBoard = UIStoryboard(name: "Main", bundle: nil)
let CIVC = StoryBoard.instantiateViewController(withIdentifier: "CharacterInformationViewController") as! CharacterInformationViewController
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext// This one is created to work with Managed Object
let entity = NSEntityDescription.entity(forEntityName: "CHARACTER",in: managedContext)!
let person = NSManagedObject(entity: entity,insertInto: managedContext)
person.setValue(CHS[indexPath.row].species , forKeyPath: "species")
person.setValue(CHS[indexPath.row].name , forKeyPath: "title")
person.setValue(CHS[indexPath.row].gender, forKeyPath: "gender")
person.setValue(CHS[indexPath.row].textInfo, forKey: "information")
person.setValue(CHS[indexPath.row].age, forKey: "age")
do {// Save into our app's dedicated disk area
try managedContext.save()
people.append(person)
print(person)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "CHARACTER")
do{
let request = try managedContext.fetch(fetchRequest)
//Try to get data from table view controller class and make an object of my view controller class
for data in request{
CIVC.getName = (data.value(forKey: "title") as? String)!
CIVC.getSpecies = (data.value(forKey: "species") as? String)!
CIVC.getGender = (data.value(forKey: "gender") as? String)!
CIVC.getText = (data.value(forKey: "information") as? String)!
CIVC.getAge = (data.value(forKey: "age") as? String)!
}
}
catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
Upvotes: 1
Views: 3718
Reputation: 2398
Provided your data set isn't changing, meaning you aren't deleting rows, a common approach to this problem is to use the tag
property of each button inside the cell. You'd set the tag like so:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
let myCharacter = charArray[indexPath.row]
cell.textLabel?.font = UIFont(name: "HoeflerText-Italic", size: 27.0)
cell.textLabel?.text = myCharacter
cell.btn1.tag = indexPath.row // set tag
return cell
}
And then you'd use this tag property as an index into your data source:
@objc func didTapButton(sender: UIButton) {
let cellIndex = sender.tag
let info = charArray[cellIndex]
// do something with info
}
Another approach is to create a delegate inside a custom UITableViewCell
and set it when you dequeue each cell.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// ...
cell.delegate = self;
// ...
}
And each time the button is tapped inside the cell, have it call a method (which you define in a protocol) in it's delegate (the UIViewController
). The method can contain anything you'd like, including identifiable data. Ensure the UIViewController
conforms to this protocol.
Upvotes: 2
Reputation: 650
You are missing a didSelectRowAtIndexPath Method.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
}
https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614877-tableview?language=objc
Upvotes: 0