I have two entities in chained:
Entity: List and Territory
Their respective Tableview for each entity that passes the information through a follow-up to the ViewController, to add records of each entity.
In the VC Territories I added a TVC in the middle part, and a Button to go to the TVC of the listed class and when I pressed a row that data I sent it to the TVC that is inside the VC of the Territories class, where I have added in the middle of the screen the TVC that expects to receive the row selected in the TVC of the class Listed.
I have listed entities listed - > Territories. And I use Coredata.
How do I do that? I searched a number of times and could not find anything on the internet.
I leave you a very short video of what I'm trying to do in swift ... in Objetive C I've already achieved it.
Video: link
/////// From this view controller I want to take the selected row //////
import UIKit
import CoreData
import MessageUI
class ToDoTasksTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate, UISearchBarDelegate, MFMailComposeViewControllerDelegate {
var totalTasks: Int = 0
fileprivate var imageItemArray = imageItem
var fetchResultsController : NSFetchedResultsController<Listado>!
var lista : [Listado] = []
fileprivate var lista1 = [Listado]()
@IBOutlet weak var segment: UISegmentedControl!
@IBOutlet weak var total: UILabel!
@IBOutlet weak var label: UILabel!
@IBOutlet weak var tableview: UITableView!
func totales() {
totalTasks = fetchData(entityName: "Listado", predicate: nil, sortDescriptor: nil).count
total?.text = "\(totalTasks)"
}
override func viewDidLoad() {
super.viewDidLoad()
attemptFetch1()
}
@IBAction func enviar(_ sender: AnyObject) {
var index = 0
var body = ""
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Listado")
request.returnsObjectsAsFaults = true
var todos = ""
let result = (try! context.fetch(request))
for data in result as! [NSManagedObject] {
if let terr = data.value(forKey: "mapa") {
todos += "Territorio: \(terr)" + "\n"// + "\n"
}
if let name = data.value(forKey: "nombre") {
todos += "Nombre: \(name)" + "\n"// + "\n"
}
if let direccion = data.value(forKey: "direccion") {
todos += "Calle: \(direccion)" + "\n"// + "\n"
}
if let entreCalles = data.value(forKey: "entreCalles") {
todos += "Entre calles: \(entreCalles)" + "\n"
}
if let colonia = data.value(forKey: "colonia") {
todos += "Colonia: \(colonia)" + "\n"
}
if let ciudad = data.value(forKey: "ciudad") {
todos += "Ciudad: \(ciudad)" + "\n"
}
if let idioma = data.value(forKey: "idioma") {
todos += "Idioma: \(idioma)" + "\n"
}
if let estatus = data.value(forKey: "estatus") {
todos += "Estatus: \(estatus)" + "\n"
}
if let coordenada = data.value(forKey: "coordenada") {
todos += "Coordenada GPS: \(coordenada)" + "\n"
}
if let notas = data.value(forKey: "notas") {
todos += "Observaciones: \(notas)" + "\n" + "\n"
}
print(todos)
}
let activityController = UIActivityViewController(activityItems: [todos + "\n", self.lista.last?.imagen! as Any], applicationActivities: nil)
self.present(activityController, animated: true, completion: nil)
}
func mailComposeController(_ controller: MFMailComposeViewController!, didFinishWith result: MFMailComposeResult, error: Error!) {
dismiss(animated: true, completion: nil)
}
//MARK: - search bar related
fileprivate func setUpSearchBar() {
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 65))
searchBar.showsScopeBar = true
searchBar.scopeButtonTitles = ["Nombre","Colonia","Direccion"]
searchBar.selectedScopeButtonIndex = 0
searchBar.delegate = self
self.tableview.tableHeaderView = searchBar
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
guard !searchText.isEmpty else {
return
}
imageItemArray = CoreDataManager.fetchObj(selectedScopeIdx: searchBar.selectedScopeButtonIndex, targetText:searchText)
tableview.reloadData()
print(searchText)
}
override func viewWillAppear(_ animated: Bool) {
tableview.reloadData()
self.totales()
filtrocolonia()
}
// MARK: - Table view data source
func numberOfSections(in tableView: UITableView) -> Int {
return (fetchedResultsController1.sections?.count)!
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
{
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView(frame: CGRect(x: 0,y: 0,width: tableView.frame.width, height: 50))
view.backgroundColor = UIColor.darkGray
let label = UILabel(frame: CGRect(x: 15,y: 4,width: 400,height: 25))
label.text = self.tableView(tableView, titleForHeaderInSection: section)
view.addSubview(label)
label.textColor = UIColor.white
label.textAlignment = NSTextAlignment.left
return view
}
func filtrocolonia() {
let fetchRequest1 = NSFetchRequest<NSFetchRequestResult>(entityName: "Listado")
let sortDescriptor1 = NSSortDescriptor(key: "nombre", ascending: true)
fetchRequest1.sortDescriptors = [sortDescriptor1]
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if segment.selectedSegmentIndex == 0 {
let sectionInfo = (fetchedResultsController1.sections?[section])! as NSFetchedResultsSectionInfo
let totalCompletePredicate = NSPredicate(format: "ciudad = %@", sectionInfo.name)
totalTasks = fetchData(entityName: "Listado", predicate: totalCompletePredicate, sortDescriptor: nil).count
return "Ciudad: \(sectionInfo.name)" + " (\(totalTasks))"
} else if segment.selectedSegmentIndex == 1 {
let sectionInfo = (fetchedResultsController1.sections?[section])! as NSFetchedResultsSectionInfo
let totalCompletePredicate = NSPredicate(format: "colonia = %@", sectionInfo.name)
totalTasks = fetchData(entityName: "Listado", predicate: totalCompletePredicate, sortDescriptor: nil).count
return "Colonia: \(sectionInfo.name)" + " (\(totalTasks))"
}
else if segment.selectedSegmentIndex == 2 {
let sectionInfo = (fetchedResultsController1.sections?[section])! as NSFetchedResultsSectionInfo
let sortDescriptor1 = NSSortDescriptor(key: "nombre", ascending: true)
let totalCompletePredicate = NSPredicate(format: "mapa = %@", sectionInfo.name)
totalTasks = fetchData(entityName: "Listado", predicate: totalCompletePredicate, sortDescriptor: sortDescriptor1).count
return "Territorio: \(sectionInfo.name)" + " (\(totalTasks))"
}
return nil
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = (fetchedResultsController1.sections?[section])! as NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ListadoTVCell
configureCell(cell, indexPath: indexPath)
return cell
}
func configureCell(_ cell: ListadoTVCell, indexPath: IndexPath) {
if let record = self.fetchedResultsController1.object(at: indexPath) as? Listado {
cell.configureCell(record)
}
}
// Override to support conditional editing of the table view.
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
// Edit mode
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
tableview.setEditing(editing, animated: true)
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let compartir = UITableViewRowAction(style:.normal, title: "Compartir"){
(action, indexPath) in
var listaa : Listado!
let cell = self.tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ListadoTVCell
self.configureCell(cell, indexPath: indexPath)
let n = cell.nombre.text
let r = cell.referencia.text
let d = cell.direccion.text
let c = cell.colonia.text
let e = cell.calles.text
let u = cell.coordenada.text
let no = cell.notas.text
let f = cell.imagenView.image
let estatus = cell.estatus.text
let idioma = cell.idioma.text
let ciudad = cell.ciudad.text
let nombre = "Nombre: " + n!
let reference = "Territorio: " + r!
let dir = "Direccion: " + d!
let col = "Colonia: " + c!
let call = "Entre calles: " + e!
let ubicacion = "Ubicacion GPS: " + u!
let estatus1 = "Estatus: " + estatus!
let idioma1 = "Idioma: " + idioma!
let ciudad1 = "Ciudad: " + ciudad!
let espacio = " "
let espacio1 = " "
let not = "Notas: " + no!
let activityController = UIActivityViewController(activityItems: [ reference,espacio, nombre,dir, col, call,ubicacion,estatus1, idioma1, ciudad1, espacio1, not, f, self.lista.last?.imagen! as Any], applicationActivities: nil)
self.present(activityController, animated: true, completion: nil)
}
let deleteAction = UITableViewRowAction(style: .destructive, title: "Eliminar") {
(action,indexPath) in
let alertController = UIAlertController(title: "¡Atención!", message: "¿Seguro que quieres eliminarlo?", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Aceptar", style: .destructive, handler:
{ (action:UIAlertAction) -> Void in
let objectToDelete = self.fetchedResultsController1.object(at: indexPath) as! NSManagedObject
context.delete(objectToDelete)
self.totales()
do {
try context.save()
} catch {
print("Error in deleting record from fetched results controller")
}
}))
alertController.addAction(UIAlertAction(title: "Cancelar", style: .cancel, handler:
{ (action:UIAlertAction) -> Void in}))
self.present(alertController, animated: true, completion: nil)
do {
try context.save()
} catch {
print("Error in deleting record from fetched results controller")
}
}
return [deleteAction, compartir]
}
func alerta (){
let alertController = UIAlertController(title: "¡Atencion!", message: "¿Seguro que quieres eliminarlo?", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .destructive, handler: nil)
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "editTaskSegue" {
let destination = segue.destination as! AddEditViewController
let indexPath = tableview.indexPathForSelectedRow
destination.itemToEdit = fetchedResultsController1.object(at: indexPath!) as? Listado
}
if segue.identifier == "getDatos" {
let destination = segue.destination as! ViewController
let indexPath = tableview.indexPathForSelectedRow
destination.lista = [fetchedResultsController1.object(at: indexPath!) as? Listado] as! [Listado]
}
}
@IBAction func segmento(_ sender: UISegmentedControl) {
// attemptFetch () // tableView.reloadData ()
attemptFetch1()
tableview.reloadData()
totales()
}
func attemptFetch1() {
if segment.selectedSegmentIndex == 0 {
setFetchedResults()
do {
try self._fetchedResultsController1?.performFetch()
totales()
} catch {
let error = error as NSError
print("\(error), \(error.userInfo)")
}
} else if segment.selectedSegmentIndex == 1{
setFetchedResults1()
do {
try self._fetchedResultsController1?.performFetch()
totales()
} catch {
let error = error as NSError
print("\(error), \(error.userInfo)")
}
} else if segment.selectedSegmentIndex == 2{
setFetchedResults2()
do {
try self._fetchedResultsController1?.performFetch()
totales()
} catch {
let error = error as NSError
print("\(error), \(error.userInfo)")
}
}
}
func attemptFetch() {
setFetchedResults()
do {
try self._fetchedResultsController1?.performFetch()
totales()
} catch {
let error = error as NSError
print("\(error), \(error.userInfo)")
}
}
// func setFetchedResults () { let section: String? = self.segment.selectedSegmentIndex == 0? "city": nil
print(section)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Listado")
let sortDescriptor = NSSortDescriptor(key: "ciudad", ascending: true)
let sortDescriptor1 = NSSortDescriptor(key: "nombre", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor, sortDescriptor1]
// let sortDescriptor1 = NSSortDescriptor (key: "city", ascending: true) // fetchRequest.sortDescriptors = [sortDescriptor1]
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: section, cacheName: nil)
controller.delegate = self
self._fetchedResultsController1 = controller
totales()
}
func setFetchedResults1() {
let sectiones: String? = self.segment.selectedSegmentIndex == 1 ? "colonia" : nil
let fetchRequest1 = NSFetchRequest<NSFetchRequestResult>(entityName: "Listado")
let sortDescriptor = NSSortDescriptor(key: "colonia", ascending: true)
let sortDescriptor1 = NSSortDescriptor(key: "nombre", ascending: true)
fetchRequest1.sortDescriptors = [sortDescriptor, sortDescriptor1]
let controller = NSFetchedResultsController(fetchRequest: fetchRequest1, managedObjectContext: context, sectionNameKeyPath: sectiones, cacheName: nil)
controller.delegate = self
self._fetchedResultsController1 = controller
}
func setFetchedResults2() {
let sectiones: String? = self.segment.selectedSegmentIndex == 2 ? "mapa" : nil
let fetchRequest1 = NSFetchRequest<NSFetchRequestResult>(entityName: "Listado")
let sortDescriptor = NSSortDescriptor(key: "mapa", ascending: true)
let sortDescriptor2 = NSSortDescriptor(key: "nombre", ascending: true)
fetchRequest1.sortDescriptors = [sortDescriptor, sortDescriptor2]
let controller = NSFetchedResultsController(fetchRequest: fetchRequest1, managedObjectContext: context, sectionNameKeyPath: sectiones, cacheName: nil)
controller.delegate = self
self._fetchedResultsController1 = controller
}
// Mark: - NSFetchedResultsController Implementation
var _fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>? = nil
var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult> {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Listado")
fetchRequest.fetchBatchSize = 20
fetchRequest.resultType = .managedObjectResultType
let sortDescriptor = NSSortDescriptor(key: "nombre", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
let sortDescriptor1 = NSSortDescriptor(key: "nombre", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor1]
_fetchedResultsController = NSFetchedResultsController<NSFetchRequestResult>(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: "ciudad", cacheName: nil)
_fetchedResultsController?.delegate = self
do {
try _fetchedResultsController?.performFetch()
} catch {
print("Issue in fetching records with the help of NSFetchedResultsController")
}
return _fetchedResultsController!
}
func FRC () {
let fetchRequest : NSFetchRequest<Listado> = NSFetchRequest(entityName: "Listado")
let sortDesc = NSSortDescriptor(key: "nombre", ascending: true)
fetchRequest.sortDescriptors = [sortDesc]
if let container = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer{
let context = container.viewContext
self.fetchResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
self.fetchResultsController.delegate = self
do{
try fetchResultsController.performFetch()
self.lista = fetchResultsController.fetchedObjects!
}
catch{
print("Error: " + error.localizedDescription)
}
}
}
// Mark: - NSFetchedResultsController Implementation II
var _fetchedResultsController1: NSFetchedResultsController<NSFetchRequestResult>? = nil
var fetchedResultsController1: NSFetchedResultsController<NSFetchRequestResult> {
if _fetchedResultsController1 != nil {
return _fetchedResultsController1!
}
let fetchRequest1 = NSFetchRequest<NSFetchRequestResult>(entityName: "Listado")
fetchRequest1.fetchBatchSize = 20
fetchRequest1.resultType = .managedObjectResultType
let sortDescriptor1 = NSSortDescriptor(key: "nombre", ascending: true)
let sortDescriptor2 = NSSortDescriptor(key: "nombre", ascending: true)
fetchRequest1.sortDescriptors = [sortDescriptor2,sortDescriptor1]
_fetchedResultsController1 = NSFetchedResultsController<NSFetchRequestResult>(fetchRequest: fetchRequest1, managedObjectContext: context, sectionNameKeyPath: "ciudad", cacheName: nil)
_fetchedResultsController1?.delegate = self
do {
try _fetchedResultsController1?.performFetch()
} catch {
print("Issue in fetching records with the help of NSFetchedResultsController")
}
return _fetchedResultsController1!
}
// let section: String? = self.segment.selectedSegmentIndex == 1? "List.city": nil
//
// print (section)
// Mark: - FRC - Delegate Methods
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableview.beginUpdates()
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableview.endUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
let sectionIndexSet = IndexSet(integer: sectionIndex)
switch type {
case .insert:
self.tableview.insertSections(sectionIndexSet, with: .fade)
case .delete:
self.tableview.deleteSections(sectionIndexSet, with: .left)
case .update:
self.tableview.reloadData()
default:
return
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
tableview.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
tableview.deleteRows(at: [indexPath!], with: .left)
case .update:
configureCell(tableview.cellForRow(at: indexPath!)! as! ListadoTVCell, indexPath: indexPath!)
case .move:
tableview.deleteRows(at: [indexPath!], with: .left)
tableview.insertRows(at: [newIndexPath!], with: .fade)
self.lista = controller.fetchedObjects as! [Listado]
default:
return
}
}