Segue not going on Table Cell click - ios

I am having a problem with my TableCell Segue.
I have setup a Segue with the identifier ShowAssesment on the prototype cell to Show a navigation controller connected to a table view, but when i click a cell it just highlights it and nothing happens.
class ViewController: UIViewController, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var subjects = [NSManagedObject]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UITableViewCell.self,
forCellReuseIdentifier: "Cell")
}
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return subjects.count
}
func tableView(tableView: UITableView,
cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier("Cell")
let check = subjects[indexPath.row]
cell!.textLabel!.text =
check.valueForKey("name") as? String
return cell!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func addName(sender: AnyObject) {
let alert = UIAlertController(title: "New Subject", message: "Add a new Subject", preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Save",
style: .Default,
handler: { (action:UIAlertAction) -> Void in
let textField = alert.textFields!.first
self.saveName(textField!.text!)
self.tableView.reloadData()
})
let cancelAction = UIAlertAction(title: "Cancel",
style: .Default) { (action: UIAlertAction) -> Void in
}
alert.addTextFieldWithConfigurationHandler {
(textField: UITextField) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
presentViewController(alert,
animated: true,
completion: nil)
}
func saveName(name: String) {
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Subjects",
inManagedObjectContext:managedContext)
let check = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
check.setValue(name, forKey: "name")
do {
try managedContext.save()
subjects.append(check)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Subjects")
do {
let results =
try managedContext.executeFetchRequest(fetchRequest)
subjects = results as! [NSManagedObject]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle,forRowAtIndexPath indexPath: NSIndexPath) {
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "ShowAssesment") {
let indexPath = tableView.indexPathForCell((sender as? UITableViewCell)!)
let listVC = segue.destinationViewController as? AssesmentViewController
let subject = subjects[indexPath!.row]
listVC?.assesments = ["Death"]
}
}
}

I don't know if you have setup your segue properly and connect it to a button in cell or so but if you wan't to be on cell tap you need to implement didselectrow and perform segue from code like
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("ShowAssesment", sender: self);
}

Check to make sure you set it up correctly. You also might try something like
func tableView(tableView:UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
self.performSegueWithIdentifier("ShowAssesment", sender: tableView.cellForRowAtIndexPath(indexPath))
}

Related

Swift - can't reload Data from TableView after add button action

I'm new to Swift and need your help.
I created a TableViewController with a custom cell.
Also I created a "add" Button in navigation bar to add a new value to my tableview.
Saving the values in Core Data and fetch them in viewWillAppear.
When pressing the add button a UIAlertController shows up which i had customized like i needed. I added a cancel action and a ok action but when i press the ok button from the alert the new value don't shows up in my tableview. I have to switch to an other viewcontroller that the tableview shows it.
I added groupsTableView.reloadData()on different points in my code but cant get it to work.
Hope someone can help me out!
Code from MasterViewController:
import UIKit
import CoreData
class MasterViewController: UITableViewController {
var groups: [Groups] = []
#IBOutlet weak var groupsTableView: UITableView!
var groupsTextField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
groupsTableView.delegate = self
groupsTableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewWillAppear(_ animated: Bool) {
// Core date initialization
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<Groups> = Groups.fetchRequest()
do {
groups = try managedContext.fetch(fetchRequest)
groupsTableView.reloadData()
} catch {
// TODO: error handling
print("Could not fetch groups")
}
navigationItem.leftBarButtonItem = editButtonItem
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject))
navigationItem.rightBarButtonItem = addButton
}
// MARK: - add new Group
#objc func insertNewObject() {
let addButtonAlert = UIAlertController(title: "Neue Gruppe", message: "Füge eine neue Gruppe deiner Liste hinzu", preferredStyle: .alert)
addButtonAlert.addTextField { (UITextField) in
self.groupsTextField = UITextField
self.groupsTextField?.placeholder = "Name der Gruppe"
self.groupsTextField?.clearButtonMode = .whileEditing
}
let okAction = UIAlertAction(title: "Hinzufügen", style: .default, handler: addNewGroup)
let cancelAction = UIAlertAction(title: "Abbrechen", style: .cancel, handler: nil)
addButtonAlert.addAction(okAction)
addButtonAlert.addAction(cancelAction)
self.present(addButtonAlert, animated: true, completion: nil)
}
func addNewGroup(_:UIAlertAction) -> Void {
let group = Groups(groupId: UUID(), groupTitle: groupsTextField!.text ?? "")
do {
try group?.managedObjectContext?.save()
groupsTableView.reloadData()
} catch {
// TODO: error handling
print("Could not save group")
}
}
// MARK: - Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let destination = segue.destination as? DetailViewController,
let selectedRow = self.groupsTableView.indexPathForSelectedRow?.row else {
return
}
destination.group = groups[selectedRow]
destination.title = groups[selectedRow].groupTitle
}
// MARK: - delete Group
func deleteGroup(at indexPath: IndexPath) {
let group = groups[indexPath.row]
guard let managedContext = group.managedObjectContext else {
return
}
managedContext.delete(group)
do {
try managedContext.save()
groups.remove(at: indexPath.row)
groupsTableView.deleteRows(at: [indexPath], with: .automatic)
} catch {
//TODO: error handling
print("Could not delete Group")
groupsTableView.reloadRows(at: [indexPath], with: .automatic)
}
}
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return groups.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = groupsTableView.dequeueReusableCell(withIdentifier: "GroupsTableViewCell", for: indexPath) as! GroupsTableViewCell
let object = groups[indexPath.row]
cell.groupTitleLabel?.text = object.groupTitle
return cell
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
deleteGroup(at: indexPath)
}
}
}
Add group item to your groups array and after that reload your tableview as shown below:-
func addNewGroup(_:UIAlertAction) -> Void {
let group = Groups(groupId: UUID(), groupTitle: groupsTextField!.text ?? "")
do {
try group?.managedObjectContext?.save()
self.groups.append(group)
groupsTableView.reloadData()
} catch {
// TODO: error handling
print("Could not save group")
}
}

Value of type 'Item' has no member 'parentCategory'

I have 2 entities
I'm using XCode 10 right now, I am not sure if I did something wrong or XCode bug.
I added 1 line into these lines
let newItem = Item(context: self.context)
newItem.title = textField.text!
newItem.done = false
newItem.parentCategory = self.selectedCategory <--------- ADD HERE
self.itemArray.append(newItem)
self.saveItems()
Any hints for me on why this is happening ?
TodoListVC
//
// TodoListVC
// ListHue
// Copyright © 2018 LR Web Design. All rights reserved.
//
import UIKit
import CoreData
class TodoListVC: UITableViewController {
var itemArray = [Item]()
var selectedCategory : Category? {
didSet {
loadItems()
}
}
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
// ---------------------------------------------------------------------------------------------------------
//MARK - viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
print(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask))
}
// ---------------------------------------------------------------------------------------------------------
//MARK - Datasource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "listItemCell", for: indexPath)
let item = itemArray[indexPath.row]
cell.textLabel?.text = item.title
cell.accessoryType = item.done == true ? .checkmark : .none
return cell
}
// ---------------------------------------------------------------------------------------------------------
//MARK - Delegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
context.delete(itemArray[indexPath.row])
itemArray.remove(at: indexPath.row)
itemArray[indexPath.row].done = !itemArray[indexPath.row].done
self.saveItems()
tableView.deselectRow(at: indexPath, animated: true)
}
// ---------------------------------------------------------------------------------------------------------
//MARK - Add new item
#IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
var textField = UITextField()
let alert = UIAlertController(title: "Add New Item", message: "", preferredStyle: .alert)
//action
let action = UIAlertAction(title: "Add Item", style: .default) { (action) in
let newItem = Item(context: self.context)
newItem.title = textField.text!
newItem.done = false
newItem.parentCategory = self.selectedCategory
self.itemArray.append(newItem)
self.saveItems()
}
alert.addTextField { (alertTextField) in
alertTextField.placeholder = "Create new item"
textField = alertTextField
}
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
// ---------------------------------------------------------------------------------------------------------
//MARK - Model Manipulation Methods
func saveItems() {
do {
try context.save()
} catch {
print("Error saving context, \(error)")
}
self.tableView.reloadData()
}
func loadItems(with request: NSFetchRequest<Item> = Item.fetchRequest()) {
let predicate = NSPredicate(format: "parentCategory.name MATCHES %#", selectedCategory?.name!)
request.predicate = predicate
do {
itemArray = try context.fetch(request)
} catch {
print("Error fetching data from the context, \(error)")
}
self.tableView.reloadData()
}
}
//MARK: - Search bar methods
extension TodoListVC : UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
let request : NSFetchRequest<Item> = Item.fetchRequest()
request.predicate = NSPredicate(format: "title CONTAINS[cd] %#", searchBar.text!)
request.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
loadItems(with: request)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text?.count == 0 {
loadItems()
DispatchQueue.main.async {
searchBar.resignFirstResponder()
}
}
}
}
CategoryVC
//
// CategoryVC.swift
// ListHue
// Copyright © 2018 LR Web Design. All rights reserved.
//
import UIKit
import CoreData
class CategoryVC: UITableViewController {
var categories = [Category]()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
override func viewDidLoad() {
super.viewDidLoad()
loadCategories()
}
// ---------------------------------------------------------------------------------------------------------
//MARK - Table View Datasource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for: indexPath)
let category = categories[indexPath.row]
cell.textLabel?.text = category.name
return cell
}
// ---------------------------------------------------------------------------------------------------------
//MARK - Table View Delegate Methods
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "goToItems", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! TodoListVC
//get the category of the selected cell
if let indexPath = tableView.indexPathForSelectedRow {
//set the property
destinationVC.selectedCategory = categories[indexPath.row]
}
}
// ---------------------------------------------------------------------------------------------------------
//MARK - Data Manipulation Methods
#IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
print("click")
var textField = UITextField()
let alert = UIAlertController(title: "Add New Category", message: "", preferredStyle: .alert)
//action
let action = UIAlertAction(title: "Add Category", style: .default) { (action) in
let newCategory = Category(context: self.context)
newCategory.name = textField.text!
self.categories.append(newCategory)
self.saveCategories()
}
alert.addTextField { (alertTextField) in
alertTextField.placeholder = "Create new item"
textField = alertTextField
}
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
// ---------------------------------------------------------------------------------------------------------
//MARK - Add New Categories
func saveCategories() {
do {
try context.save()
} catch {
print("Error saving context, \(error)")
}
self.tableView.reloadData()
}
func loadCategories(with request: NSFetchRequest<Category> = Category.fetchRequest()) {
do {
categories = try context.fetch(request)
} catch {
print("Error fetching data from the context, \(error)")
}
self.tableView.reloadData()
}
}
I got the diagram backward, thanks to #Larme, and #Ladislav helped me to know that.

Edit the contents list of TableViewCell in Swift

I have a TableViewController with lists of data entry using CoreData. I also have ViewController with UITextView as linked by Segue to TableViewController. I have completed operations like add, save and delete on items.
Now I am working on edit by linking the selected TableViewCell to UITextView on next ViewController.I have created an action DONE on ViewController.I am able to pass data from selected Cell to TextView of next ViewController using Segue.
Now, I need to update the edited text on UITextView by clicking DONE button to back to Cells of TableViewController and also save data to CoreData. Plzz give the genuine advices and suggestions....I am new to Swift and I have enclosed my code here.
import UIKit
import CoreData
class ToDoTableViewController: UITableViewController {
var listItems = [NSManagedObject]()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.add, target: self , action: #selector(ToDoTableViewController.addItem))
}
func addItem(){
let alertController = UIAlertController(title: "To Do Tasks Lists!!!!", message: "Write Down...", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Confirm", style: UIAlertActionStyle.default, handler: ({
(_) in
if let field = alertController.textFields![0] as? UITextField {
self.saveItem(itemToSave: (field.text!))
self.tableView.reloadData()
}
}
))
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil)
alertController.addTextField(configurationHandler: ({
(textField) in
textField.placeholder = "Type in Something!!!!"
}))
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}
func saveItem(itemToSave : String){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entity(forEntityName: "ListEntity", in: managedContext)
let item = NSManagedObject(entity: entity!, insertInto: managedContext)
item.setValue(itemToSave, forKey: "item")
do {
try managedContext.save()
listItems.append(item)
}
catch {
print("Error")
}
}
override func viewWillAppear(_ animated: Bool) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ListEntity")
do{
let results = try managedContext.fetch(fetchRequest)
listItems = results as! [NSManagedObject]
}
catch {
print("Error")
}
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let objectToDelete = listItems[indexPath.row]
listItems.remove(at: indexPath.row)
managedContext.delete(objectToDelete)
tableView.deleteRows(at: [indexPath], with: .fade)
do {
try managedContext.save()
}
catch {
print("Error")
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listItems.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! as UITableViewCell
let item = listItems[indexPath.row]
cell.textLabel?.text = item.value(forKey: "item") as! String?
cell.backgroundColor = UIColor.clear
return cell
}
func getIndexPathForSelectedCell() -> IndexPath?
{
var indexPath2:IndexPath?
if tableView.indexPathsForSelectedRows!.count > 0 {
indexPath2 = tableView.indexPathsForSelectedRows![0]
}
return indexPath2
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "detailView")
{
if let indexPath2 = getIndexPathForSelectedCell()
{
// here write code for move to next controller.
let vc = segue.destination as! TextEditViewController
//vc.FirstString = listItems[(indexPath2 as NSIndexPath).row] as String
let item = listItems[(indexPath2 as NSIndexPath).row]
vc.FirstString = (item.value(forKey: "item") as! String?)!
}
}
}
}
//TextEditViewController
import UIKit
import CoreData
class TextEditViewController: UIViewController {
#IBOutlet weak var textEdit: UITextView!
var FirstString = String()
override func viewDidLoad() {
super.viewDidLoad()
textEdit.text = FirstString
print(self.FirstString)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Pass your CoreData model reference to next screen:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "detailView")
{
if let indexPath2 = getIndexPathForSelectedCell()
{
// here write code for move to next controller.
let vc = segue.destination as! TextEditViewController
//vc.FirstString = listItems[(indexPath2 as NSIndexPath).row] as String
let item = listItems[(indexPath2 as NSIndexPath).row]
vc.FirstString = (item.value(forKey: "item") as! String?)!
vc.recentItem = item; //Like this. Create a recentItem refrence to your next controller of NSManagedObject or your custom core data modal.
}
}
}
When you are done with your editing in TextEditViewController:
recentItem.item = "String" //Your updated string
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
do {
try managedContext.save()
}
catch {
print("Error")
}
Hope this will work...!!

The top of tableView has some empty area

The issue occurs as the pic .
at the top of tableView has some empty area
The interface is that viewController(embed in navigationController).I put one tableView on it.And construct its constraints.But run the code ,and the issue occurs .I wanna try to use two methods to solve it ,but no any changes.
self.automaticallyAdjustsScrollViewInsets = true
I adjust the constraints of tableView to superView,I set the constraint of top to -100,it works well.
The code as below:
import UIKit
import CoreData
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var people:[NSManagedObject] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.title = "My book"
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName:"Person")
do {
people = try managedContext.fetch(fetchRequest)
}catch let error as NSError {
print("Cannot fetch \(error),\(error.userInfo)")
}
}
#IBAction func addName(_ sender: AnyObject) {
let alert = UIAlertController(title: "New name", message: "Add a name", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save", style: .default) { [unowned self] action in
guard let textField = alert.textFields?.first,
let nameToSave = textField.text else {return
}
self.save(name: nameToSave)
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default)
alert.addTextField()
alert.addAction(saveAction)
alert.addAction(cancelAction)
present(alert,animated: true)
}
func save(name:String) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Person", in: managedContext)
let person = NSManagedObject(entity: entity!, insertInto: managedContext)
person.setValue(name, forKey: "name")
do {
try managedContext.save()
people.append(person)
}catch let error as NSError {
print("Could not save\(error),\(error.userInfo)")
}
}
}
extension ViewController :UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return people.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let person = people[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = person.value(forKey: "name") as? String
return cell
}
}
You should put constraint for the tableView from storyboard and set top space = 0
You can also try setting the edgesForExtendedLayout in your viewDidLoad method:
self.edgesForExtendedLayout = []
try to implement
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return .min
}

Can't pass variable into prepareForSegue in Swift?

I'm trying to pass selectedName to VC #2 (BrandTableViewController). If I println(selectedName) in viewDidDisappear I get the value, however, the value is nil when it's in prepareForSegue? Can anyone see why?
import UIKit
import CoreData
class NameTableViewController: UITableViewController, UITableViewDelegate {
//Changes [String] to [NSManagedObject]
var people = [NSManagedObject]()
#IBOutlet var nameTableView: UITableView!
var selectedName: Person?
override func viewDidLoad() {
super.viewDidLoad()
title = "\"People\""
nameTableView.delegate = self
// 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()
// Retreive the managedObjectContext from AppDelegate
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
// Print it to the console
println(managedObjectContext)
}
// Mark: - Add Button Alert
#IBAction func addButton(sender: AnyObject) {
var alert = UIAlertController(title: "New name",
message: "Add a new name",
preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Save",
style: .Default) { (action: UIAlertAction!) -> Void in
let textField = alert.textFields![0] as! UITextField
self.saveName(textField.text)
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel",
style: .Default) { (action: UIAlertAction!) -> Void in
}
alert.addTextFieldWithConfigurationHandler {
(textField: UITextField!) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
presentViewController(alert,
animated: true,
completion: nil)
}
//function to save a name (code from: http://www.raywenderlich.com/85578/first-core-data-app-using-swift)
func saveName(name: String) {
//1
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let entity = NSEntityDescription.entityForName("Person",
inManagedObjectContext:
managedContext)
let person = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext:managedContext)
//3
person.setValue(name, forKey: "name")
//4
var error: NSError?
if !managedContext.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
//5
people.append(person)
}
// MARK: - Table view data source
// override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// // #warning Potentially incomplete method implementation.
// // Return the number of sections.
// return 1
// }
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return people.count
}
private struct Storyboard {
static let CellReuseIdentifier = "Name"
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(Storyboard.CellReuseIdentifier, forIndexPath: indexPath) as! UITableViewCell
let person = people[indexPath.row]
cell.textLabel!.text = person.valueForKey("name") as? String
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let row = self.tableView.indexPathForSelectedRow()!.row
println("row \(row) was selected")
selectedName = people[indexPath.row] as? Person
println(selectedName)
// if let unWrappedSelectedName = selectedName {
// // println(unWrappedSelectedName)
// }
// else {
// println("no person was selected in didSelectRowAtIndexPath")
// }
}
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
let personToDelete = people[indexPath.row]
//abstract this into helper function later
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
managedContext.deleteObject(personToDelete)
self.fetchCoreData()
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the item to be re-orderable.
return true
}
*/
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
fetchCoreData()
}
//Helper Function to Fetch Core Data
func fetchCoreData() {
//1
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let fetchRequest = NSFetchRequest(entityName:"Person")
//3
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest,
error: &error) as? [NSManagedObject]
if let results = fetchedResults {
people = results
} else {
println("Could not fetch \(error), \(error!.userInfo)")
}
}
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let btvc = segue.destinationViewController as? BrandsTableTableViewController {
if let identifer = segue.identifier {
if identifer == "segueToBrands" {
btvc.selectedName = selectedName
println(selectedName)
}
}
}
else {
println("we have a segue problem")
}
}
The prepareForSegue: method is called before tableView:didSelectRowAtIndexPath: method.And I saw that you only assign selectedName in method didSelectRowAtIndexPath.So selectedName will always be nil in prepareForSegue.
You can assign selectedName in tableView:willSelectRowAtIndexPath:
override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) {
let row = self.tableView.indexPathForSelectedRow()!.row
println("row \(row) was selected")
selectedName = people[indexPath.row] as? Person
println(selectedName)
}
In your preprareForSegue() you can access the selected cell (or cells) as such:
override func prepareForSegue (segue: UIStoryboardSegue, sender: AnyObject?) {
switch segue.identifier ?? "" {
case "theSegue":
if let indexPath = tableView.indexPathForSelectedRow () {
// get what you need from the cell or the DataSource object
let controller = segue.destinationViewController as! PersonController
controller.person = people[indexPath.row]
}
// ...
}
}

Resources