Receiving Thread 1: EXC_BAD_ACCESS (code=1, address=0x6b49dedf6a0) Error - swift

I am trying to build a simple To Do app with Core Data.
In CoreData Model, I have created an Entity named "ToDoCoreData". It has one attribute "newToDoItem" type of String.
In CellForRowAt method I'm receiving the following error
Thread 1: EXC_BAD_ACCESS (code=1, address=0x6b49dedf6a0) - but everytime I rerun the app the newly added ToDo appeares in row.
The code is below. Would be glad if someone could help, please.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var toDoList:[ToDoCoreData] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
override func viewWillAppear(_ animated: Bool) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<ToDoCoreData> = ToDoCoreData.fetchRequest()
do {
toDoList = try context.fetch(fetchRequest)
} catch {
print(error.localizedDescription)
}
}
#IBAction func addNewToDo(_ sender: UIBarButtonItem) {
let ac = UIAlertController(title: "Add Task", message: "add New Task", preferredStyle: .alert)
let ok = UIAlertAction(title: "Add", style: .default) { (action) in
let textField = ac.textFields?[0]
// self.toDoList.insert((textField?.text)!, at: 0)
self.saveToDo(newToDoItem: (textField?.text)!)
self.tableView.reloadData()
}
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
ac.addTextField { textfield in
}
ac.addAction(ok)
ac.addAction(cancel)
present(ac, animated: true, completion: nil)
}
func saveToDo(newToDoItem: String) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "ToDoCoreData", in: context)
let taskObject = NSManagedObject(entity: entity!, insertInto: context) as! ToDoCoreData
taskObject.newToDoItem = newToDoItem
do {
try context.save()
toDoList.append(taskObject)
print("Success!")
} catch {
print(error.localizedDescription)
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
toDoList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
let toDo = toDoList[indexPath.row]
cell.rowLabel.text = toDo.newToDoItem
return cell
}
}

Related

Error about making Table View from String and model

in swift UIKit
Error about making Table View from String and model
Could not cast value of type 'CloudApp.addCatogrey' (0x104948470) to 'Swift.String' (0x1052195b8).
An error occurs when I press send
I want to display the data for one of the sections through the model (addCatogrey)
view control file
import UIKit
class ViewController: UIViewController {
//MARK: arry data
let sectionMenu = ["all", "Fav", "Delete"]
var arrS1 : [addCatogrey] = []
var arrS2 = ["favorite"]
var arrS3 = ["delete other"]
var sectionData : [Int: [Any]] = [:]
//MARK: Outlet
#IBOutlet weak var addNewCatogery: UIBarButtonItem!
#IBOutlet var tableCatogery: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
sectionData = [0 : arrS1 , 1 : arrS2, 2 : arrS3]
self.arrS1 = helperCora().getCatog()
}
#IBAction func addMenuNew(_ sender: Any) {
let alert = UIAlertController(title: "Create an album", message: "", preferredStyle: .alert)
alert.addTextField(configurationHandler: nil)
alert.textFields![0].placeholder = "name album"
alert.textFields![0].textAlignment = .right
alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: "save", style: .default, handler: { ـ in
if let textFileds = alert.textFields {
let links = textFileds[0].text
self.arrS1.append(addCatogrey(nameCatog: links!))
helperCora().storeCatog(name: addCatogrey(nameCatog: links!))
self.sectionData = [0 : self.arrS1 , 1 : self.arrS2, 2 : self.arrS3]
self.tableCatogery.reloadData()
}
}))
self.present(alert, animated: true, completion: nil)
}
}
extension ViewController : UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return sectionData.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (sectionData[section]?.count)!
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionMenu[section]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellMenu
cell.textMenu.text = sectionData[indexPath.section]![indexPath.row] as! String
return cell
}
}
model file
struct addCatogrey {
var nameCatog : String
}
Coradata file [SAVE and GET]
import UIKit
import CoreData
class helperCora : ViewController {
//MARK: Data For Menu --------- 1
func storeCatog (name : addCatogrey) {
guard let AppDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let mangeContext = AppDelegate.persistentContainer.viewContext
guard let myEntity = NSEntityDescription.entity(forEntityName: "Entity", in: mangeContext) else { return }
let nameCat = NSManagedObject.init(entity: myEntity, insertInto: mangeContext)
nameCat.setValue(name.nameCatog, forKey: "nameCat")
do {
try mangeContext.save()
print("========== Secsess =========")
}catch {
print("========== Error =========")
}
}
//MARK: Data For Menu --------- 2
func getCatog () -> [addCatogrey] {
var catog : [addCatogrey] = []
guard let AppDelegate = UIApplication.shared.delegate as? AppDelegate else {return []}
let context = AppDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Entity")
do {
let reselt = try context.fetch(fetchRequest) as! [NSManagedObject]
for mangeCatoj in reselt {
let title = mangeCatoj.value(forKey: "nameCat") as! String
let Catogery = addCatogrey(nameCatog: title)
catog.append(Catogery)
}
print("====== secsecc ========")
}catch {
print("====== error ========")
}
return catog
}
}

how to call/show action sheet for taking or choose photo from gallery on Main VC after tapped on TableViewCell Image(swift)

Here I Try MVVM pattern to achieve TableView but for showing alert I face problems , it compiles successfully but not showing alert.
[Result] on the tapped on profile pic which is in tableview cell, I want to show alert
TableViewCell
import Foundation
import UIKit
class ParentsImageCell : UITableViewCell {
weak var myVC : ProfileOfParentsDetailsViewController?
var parentProfileVC = ProfileOfParentsDetailsViewController()
#IBOutlet weak var imageProfile : UIImageView!
var items : ParentProfileViewModelItem? {
didSet {
guard let items = items as? ParentProfileViewModelProfileItem else {
return
}
imageProfile?.image = UIImage(named: items.profileImg)
}
}
static var nib:UINib {
return UINib(nibName: identifier, bundle: nil)
}
static var identifier: String {
return String(describing: self)
}
override func awakeFromNib() {
super.awakeFromNib()
imageProfile?.layer.cornerRadius = 62
imageProfile?.clipsToBounds = true
imageProfile?.contentMode = .scaleAspectFill
imageProfile?.backgroundColor = UIColor.lightGray
//Add Tapped Gesture
imageProfile.isUserInteractionEnabled = true
let gesture = UITapGestureRecognizer(
target: self,
action: #selector(didTappedChangeProfilePic))
gesture.numberOfTapsRequired = 1
gesture.numberOfTouchesRequired = 1
imageProfile.addGestureRecognizer(gesture)
}
#objc private func didTappedChangeProfilePic(){
print("tapped on imageView")
presentPhotoActionSheet()
}
override func prepareForReuse() {
super.prepareForReuse()
imageProfile?.image = nil
}
}
extension ParentsImageCell : UIImagePickerControllerDelegate ,UINavigationControllerDelegate {
func presentPhotoActionSheet(){
let actionSheet = UIAlertController(title: "Profile Picture", message: "How would you write to select a picture", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: nil))
actionSheet.addAction(UIAlertAction(title: "Take Photo", style: .default, handler: {[weak self] _ in
self?.presentCamera()
}))
actionSheet.addAction(UIAlertAction(title: "Choose Photo", style: .default, handler: { [weak self]_ in
self?.presentPhotoPicker()
}))
myVC?.present(actionSheet , animated: true)
}
func presentCamera(){
let vc = UIImagePickerController()
vc.sourceType = .camera
vc.delegate = self
vc.allowsEditing = true
myVC?.present(vc , animated: true)
}
func presentPhotoPicker(){
let vc = UIImagePickerController()
vc.sourceType = .photoLibrary
vc.delegate = self
vc.allowsEditing = true
myVC?.present(vc , animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info:
[UIImagePickerController.InfoKey : Any]) {
guard let selectedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage else {
return
}
self.imageProfile.image = selectedImage
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
ViewModel
class ParentProfileViewModel: NSObject {
var items = [ParentProfileViewModelItem]()
var reloadSections: ((_ section: Int) -> Void)?
override init() {
super.init()
guard let data = dataFromFile("ServerData"),
let profile = Profile(data: data) else {
return
}
// initialization code will go here
if let profile = profile.pictureUrl {
let profileItem = ParentProfileViewModelProfileItem(profileImg: profile)
items.append(profileItem)
}
if let name = profile.fullName {
let nameItem = ParentProfileViewModelNameItem(name: name)
items.append(nameItem)
}
if let email = profile.email {
let emailItem = ParentProfileViewModelEmailItem(email: email)
items.append(emailItem)
}
let coach = profile.coach
if !coach.isEmpty {
let coachItem = ParentProfileViewModelCoachItem(coach: coach)
items.append(coachItem)
}
let candidate = profile.candidate
if !candidate.isEmpty {
let candidateItem = ParentProfileViewModelCandidateItem(candidate: candidate)
items.append(candidateItem)
}
}
}
//MARK:- TableviewDatasource & Delegates
extension ParentProfileViewModel: UITableViewDataSource {
//Number of section
func numberOfSections(in tableView: UITableView) -> Int {
return items.count
}
//Number of RowInSection
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let item = items[section]
guard item.isCollapsible else {
return item.rowCount
}
if item.isCollapsed {
return 0
} else {
return item.rowCount
}
}
//Cell for row at indexpath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// we will configure the cells here
let item = items[indexPath.section]
switch item.type {
case .profileImg:
let vc = ProfileOfParentsDetailsViewController()
if let cell = tableView.dequeueReusableCell(withIdentifier: ParentsImageCell.identifier, for: indexPath) as? ParentsImageCell {
cell.items = item
cell.myVC = vc
return cell
}
case .fullName:
if let cell = tableView.dequeueReusableCell(withIdentifier: ParentsFulNameCell.identifier, for: indexPath) as? ParentsFulNameCell {
cell.items = item
return cell
}
case .email:
if let cell = tableView.dequeueReusableCell(withIdentifier: ParentsEmailCell.identifier, for: indexPath) as? ParentsEmailCell {
cell.items = item
return cell
}
case .candidate:
if let item = item as? ParentProfileViewModelCandidateItem, let cell = tableView.dequeueReusableCell(withIdentifier: CandidatCell.identifier, for: indexPath) as? CandidatCell {
let candidate = item.candidate[indexPath.row]
cell.item = candidate
return cell
}
case .coach:
if let item = item as? ParentProfileViewModelCoachItem, let cell = tableView.dequeueReusableCell(withIdentifier: ParentCoachCell.identifier, for: indexPath) as? ParentCoachCell {
cell.item = item.coach[indexPath.row]
return cell
}
}
return UITableViewCell()
}
}
ViewController
import Foundation
import UIKit
class ProfileOfParentsDetailsViewController: UIViewController {
let viewModel = ParentProfileViewModel()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
viewModel.reloadSections = { [weak self] (section: Int) in
self?.tableView?.beginUpdates()
self?.tableView?.reloadSections([section], with: .fade)
self?.tableView?.endUpdates()
}
tableView?.dataSource = viewModel
tableView.delegate = viewModel
tableView?.estimatedRowHeight = 250
tableView?.rowHeight = UITableView.automaticDimension
tableView?.register(ParentsImageCell.nib, forCellReuseIdentifier: ParentsImageCell.identifier)
tableView?.register(ParentsEmailCell.nib, forCellReuseIdentifier: ParentsEmailCell.identifier)
tableView?.register(ParentsFulNameCell.nib, forCellReuseIdentifier: ParentsFulNameCell.identifier)
tableView?.register(CandidatCell.nib, forCellReuseIdentifier: CandidatCell.identifier)
tableView?.register(ParentCoachCell.nib, forCellReuseIdentifier: ParentCoachCell.identifier)
tableView?.register(ParentsHeaderView.nib, forHeaderFooterViewReuseIdentifier: ParentsHeaderView.identifier)
}
I try to get called alert Sheet , but I Failed and also comment about my approach towards MVVM
I try to called the tableview data source and delegate in VM
I try to get called alert Sheet , but I Failed and also comment about my approach towards MVVM
I try to called the tableview data source and delegate in VM

Cannot call value of non-function type 'UITableView?' in UITapGestureRecognizer method

My table tap gesture recogniser calls a method that displays a message informing that no row values are present, and some should be added. This happens when user touches anywhere inside the table view.
The error is in tableTapped inside the if let statement.
I've tried deleting and recreating the tableView in story builder. Also tried 'homework' instead of 'tableView' and the parameter name. Also tried removing 'self.' before 'tableView'.
I have this exact same method on another class, and it works fine so I guess there's something different about the class it's not working in. I just can't pinpoint it!
import UIKit
class homeworkViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var clear: UIButton!
#IBOutlet weak var all: UIButton!
#IBOutlet weak var chosen: UIButton!
var languages = [String]()
var chosenLanguage = String()
var chosenLanguageRemoved = false
var homeworkWords = [String]()
var chosenLanguageEnabled = false
let wordString = "words"
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(test))
let tap = UITapGestureRecognizer(target: self, action: #selector(tableTapped))
self.tableView.backgroundView = UIView()
self.tableView.backgroundView?.addGestureRecognizer(tap)
// Do any additional setup after loading the view.
}
#objc func tableTapped(tap:UITapGestureRecognizer) {
let location = tap.location(in: self.tableView)
let path = self.tableView.indexPathForRow(at: location)
if let indexPathForRow = path {
self.tableView(self.tableView, didSelectRowAt: indexPathForRow)
} else {
if homeworkWords.isEmpty == true {
let ac = UIAlertController(title: "Add Homework!", message: nil, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default)
ac.addAction(okAction)
present(ac, animated: true)
}
}
}
#IBAction func chosen(_ sender: UIButton) {
let ac = UIAlertController(title: "Use Chosen Language", message: "Add or clear choosen language words to quickly set homework.", preferredStyle: .alert)
// add user actions, "Cancel" to abort
if chosenLanguageEnabled == false {
ac.addAction(UIAlertAction(title: "Set", style: .default, handler: chosenLanguage))
}
if chosenLanguageEnabled == true {
ac.addAction(UIAlertAction(title: "Clear", style: .default, handler: clearChosenLanguage))
}
ac.addAction(UIAlertAction(title: "Cancel", style: .cancel))
}
func chosenLanguage(action: UIAlertAction!) {
homeworkWords.removeAll()
if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.hyperpolyglot.todayview") {
if var savedWords = defaults.object(forKey: "\(chosenLanguage)\(wordString)") as? [String] {
print("savedWords in chosenLanguage in homeworkViewController are: \(savedWords)")
homeworkWords = savedWords
saveWords()
savedWords.removeAll()
chosenLanguageEnabled = true
print("chosenLanguageEnabled in chosenLanguage method in homeworkViewController is: \(chosenLanguageEnabled)")
print("homeworkWords in chosenLanguage method in homeworkViewController are: \(homeworkWords)")
print("savedWords after clear all in chosenLanguage method in homeworkViewController are: \(savedWords)")
}
}
}
func clearChosenLanguage(action: UIAlertAction!) {
homeworkWords.removeAll()
saveWords()
chosenLanguageEnabled = false
}
#IBAction func allWords(_ sender: UIButton) {
homeworkWords.removeAll()
for language in languages {
if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.hyperpolyglot.todayview") {
if var savedWords = defaults.object(forKey: "\(language)\(wordString)") as? [String] {
print("savedWords array is: \(savedWords)")
homeworkWords.append(contentsOf: savedWords)
saveWords()
savedWords.removeAll()
print("allWords method homeworkWords are: \(homeworkWords)")
print("allWords savedWords after clear all: \(savedWords)")
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .default, title: "Delete") { (action, indexPath) in
self.homeworkWords.remove(at: indexPath.row)
self.saveWords()
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .left)
tableView.endUpdates()
// delete item at indexPath
if self.homeworkWords.isEmpty == true {
self.clear.isEnabled = false
self.clear.alpha = 0.25
}
}
delete.backgroundColor = UIColor.red
if let cell = tableView.cellForRow(at: indexPath) {
cell.isHighlighted = true
}
return [delete]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//print("In cellForRowAt function")
let cell = tableView.dequeueReusableCell(withIdentifier: "homework", for: indexPath)
let word = homeworkWords[indexPath.row]
cell.textLabel?.text = word.capitalized
//print(cell)
return cell
}
func loadHomeworkWords() {
if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.hyperpolyglot.todayview") {
if var savedHomeWorkWords = defaults.object(forKey: "homeworkWords") as? [String] {
print("savedLanguages array is: \(savedHomeWorkWords)")
homeworkWords.removeAll()
homeworkWords = savedHomeWorkWords
savedHomeWorkWords.removeAll()
print("savedHomeWorkWords after removeAll: \(savedHomeWorkWords)")
print("loadHomeworkWords homeworkWords are: \(homeworkWords)")
}
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadHomeworkWords()
tableView.reloadData()
}
func saveWords() {
if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.hyperpolyglot.todayview") {
defaults.set(homeworkWords, forKey: "homeworkWords")
print("saveWords homeworkWords homeworkViewController are: \(homeworkWords)")
}
}
}
I expect to see a UIAlertAction message telling the user they need to add some table row values by tapping on either the 'All words' button or 'chosen language' button, if there are no values in any of the table rows.
Instead I get the pre-compile error message:
Cannot call value of non-function type 'UITableView?'

I can't get my code to work with an outdated Swift Core Data tutorial

First off, I'm pretty new to XCode. I'm a highschool student taking a coding class.
Here is the tutorial: https://www.raywenderlich.com/115695/getting-started-with-core-data-tutorial
Can you please help me update my code to fit the new Swift update?
Error: "Value of type AppDelegate has no member managedObjectContext"
Line giving me errors:
let appDelegate =
UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
However, when I remove this, and replace it with
let delegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = delegate.persistentContainer.viewContext
lots more errors pop up.
My full code:
import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDataSource
{
#IBOutlet weak var tableView: UITableView!
#IBAction func addName(_ sender: Any)
{
let alert = UIAlertController(title: "New Name", message: "Add a new name", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save", style: .default, handler:
{
(action:UIAlertAction) -> Void in
let textField = alert.textFields!.first
self.saveName(name: textField!.text!)
self.tableView.reloadData()
})
let cancelAction = UIAlertAction(title: "Cancel", style: .default) {
(action: UIAlertAction) -> Void in
}
alert.addTextField
{
(textField: UITextField) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
present(alert, animated: true, completion: nil)
}
func saveName(name: String)
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Person", inManagedObjectContext:managedContext)
let person = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: 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)")
}
}
var people = [NSManagedObject]()
override func viewDidLoad()
{
super.viewDidLoad()
title = "\"The List\""
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//1
let appDelegate =
UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
//2
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
//3
do {
let results =
try managedContext.executeFetchRequest(fetchRequest)
people = results as! [NSManagedObject]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return people.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let person = people[indexPath.row]
cell!.textLabel!.text = person.value(forKey: "name") as? String
return cell!
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You can use a simple library (written by me) for latest Swift syntax AACoreData.
Simply assign your data model after installing the library,
AACoreData.sharedInstance().dataModel = "YourEntity"
For more guide and documentation visit the official repository AACoreData.
you should use the updated Core Data Model Tutorials for Swift 3 - that is more easy then going the hard way to convert old code.
https://www.raywenderlich.com/145692/core-data-by-tutorials-updated-for-swift-3-and-ios-10
https://www.raywenderlich.com/145809/getting-started-core-data-tutorial

How can I get the cells to print in my ViewController2?

I am trying to get my app to display the name of the selected cell on a different screen. I got it to display the word "Sample" but I want to show the name of the person selected. What can I do for it to show? It's just the one line of code I need to change in my prepareforSegue.
ViewController:
import UIKit
import CoreData
class ViewController: UIViewController,UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var ppl = [NSManagedObject]()
#IBAction func addName(sender: AnyObject) {
let alert = UIAlertController(title: "New Client",
message: "Add a new client",
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)
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Clients"
accessData()
tableView.registerClass(UITableViewCell.self,
forCellReuseIdentifier: "Cell")
tableView.reloadData()
}
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return ppl.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier("Cell")
let person = ppl[indexPath.row]
cell!.textLabel!.text =
person.valueForKey("name") as? String
return cell!
}
func tableView(tableView: UITableView,didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("SELECTED ITEM")
performSegueWithIdentifier("selectedView", sender: tableView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func saveName(name: String) {
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Person",
inManagedObjectContext:managedContext)
let person = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
person.setValue(name, forKey: "name")
do {
try managedContext.save()
ppl.append(person)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
func accessData() {
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Person")
do {
let results =
try managedContext.executeFetchRequest(fetchRequest)
ppl = results as! [NSManagedObject]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier=="selectedView") {
let dvc=segue.destinationViewController as! ViewController2
dvc.name="Sample"
//let selectedItem: NSManagedObject = ppl[self.tableView.indexPathForSelectedRow!.row] as NSManagedObject
//dvc.name = selectedItem.valueForKey("Cell") as! String
}
}
}
ViewController2:
import UIKit
class ViewController2:UIViewController{
#IBOutlet weak var userDisplay: UILabel!
var name = String()
override func viewDidLoad() {
super.viewDidLoad()
userDisplay.text = name
}
func printMe(){
print("I am a controller")
}
}
This can be done easily, instead of sending tableView as the sender when doing performSegueWithIdentifier("selectedView", sender: tableView) send the indexPath of the selected row, thus you have:
performSegueWithIdentifier("selectedView", sender: indexPath)
All you have to do then is change prepareForSegue method to be something like
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let indexPath = sender {
let cell = self.tableView.cellForRowAtIndexPath(indexPath as! NSIndexPath)
if let name = cell?.textLabel?.text {
let dvc = segue.destinationViewController as! SecondVC
dvc.name = name
}
}
}