how to put 2 text in 1 row when you add? - ios

import UIKit
import CoreData
class ViewController: UIViewController , UITableViewDataSource , UITableViewDelegate {
#IBOutlet weak var text1: UITextField!
#IBOutlet weak var text2: UITextField!
#IBOutlet weak var ttableview: UITableView!
/////
//CoreData
func saveName(name: String) {
let appDel:AppDelegate = UIApplication.shared.delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Zain",in:context)
let person1 = NSManagedObject(entity: entity!,insertInto: context)
let person2 = NSManagedObject(entity: entity!,insertInto: context)
person1.setValue(name, forKey: "man1")
person2.setValue(name, forKey: "man2")
do {
try context.save()
//5
array1.insert(person1, at: 0)
array2.insert(person2, at: 0)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
/////
#IBAction func Add(_ sender: Any) {
self.saveName(name: text1.text!)
self.saveName(name: text2.text!)
self.ttableview.reloadData()
}
//deleat row and tableview and arry
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
array1.remove(at: indexPath.row)
array2.remove(at: indexPath.row)
ttableview.deleteRows(at: [indexPath], with: .fade)
let appDel:AppDelegate = UIApplication.shared.delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.persistentContainer.viewContext
context.delete(array1[indexPath.row] as NSManagedObject)
context.delete(array2[indexPath.row] as NSManagedObject)
do {
try context.save()
} catch _ {
print("remove object error")
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array1.count
}
func ttableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array2.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = ttableview.dequeueReusableCell(withIdentifier: "cell") as! Cell
let person1 = array1[indexPath.row]
let person2 = array2[indexPath.row]
cell.lable1.text = person1.value(forKey: "man1") as! String?
cell.lable2.text = person2.value(forKey: "man2") as! String?
return cell
}
var array1 = [NSManagedObject]()
var array2 = [NSManagedObject]()
override func viewDidLoad() {
super.viewDidLoad()
ttableview.delegate = self
ttableview.dataSource = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let appDel:AppDelegate = UIApplication.shared.delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Zain")
do {
let results = try context.fetch(fetchRequest)
array1 = results as! [NSManagedObject]
array2 = results as! [NSManagedObject]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
}

Why don't you just use two labels / textFields in your tableview cells?
You will need a custom uitableviewcell for this.

Related

some problem about to show imageView from CoreData in TableView

I saved the photo and name of the movie to CoreData. entity name is movieEntity
When I try to show a photo and name of a movie in tableView, I have a problem with the picture. The name of the movie successfully visible to tableView, but the photo of the movie is not visible.
class movieViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var movie: [NSManagedObject] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
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: "movieEntity")
do {
coreDataMoviePhoto = try managedContext.fetch(fetchRequest)
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
}
extension movieViewController: UITableViewDataSource, UITableViewDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return movie.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let movieData = movie[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "movieTableViewCell", for: indexPath) as! movieTableViewCell
cell.tableViewCellImageView.image = movieData.value(forKeyPath: "img") as? UIImage
cell.tableViewTextLabel.text = movieData.value(forKeyPath: "name") as? String
return cell
}
}
here is movieTableViewCell
class CoreDataWatchlistTableViewCell: UITableViewCell {
#IBOutlet weak var tableViewTextLabel: UILabel!
#IBOutlet weak var tableViewCellImageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
}
}
As you saving image data not image in so use
if let data = movieData.value(forKeyPath: "img") as? Data{
cell.tableViewCellImageView.image = UIImage(data:data)
}else{
cell.tableViewCellImageView.image = somePlaceholderImage
}
hope its help

How can I get an array to an NSManagedObject

I am sorry if I put out silly questions but I am new to Swift. I am building an app and so far it goes quite well. But now I want to delete some rows from my tableview which gets feeded from an Array with Strings. And then I want to save/fetch that using core data. I believe I have the code for it but the problem is that I am trying to save an array full of Strings. so I get error message saying: Cannot convert value of type 'String' to expected argument type 'NSManagedObject'. And therefore I am wondering, how can I solve this? Is there any way to "add those Strings to an NSManagedObject somehow?
Here are my code:
the array :
and here are the code:
import UIKit
import CoreData
class tableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (List.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = List.self[indexPath.row]
cell.textLabel?.textColor = UIColor.white
cell.backgroundColor = UIColor.clear
return(cell)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
if editingStyle == .delete{
let rows = List[indexPath.row]
context.delete(rows)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
do{
List = try context.fetch(MealsMenu.fetchRequest()) as! [String]
}
catch{
print(error)
}
}
myTableView.reloadData()
}
#IBOutlet weak var myTableView: UITableView!
override func viewDidAppear(_ animated: Bool) {
myTableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
CoredataClass.saveItems()
CoredataClass.loadData()
}
}
You will need to create a function like this
Imagine that your Entity is Recipe which has an string attribute recipeName which contains the name of the recipe.
func fetchPersistentData() -> [String] {
var recipes = [String]()
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return recipes
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<Recipe>(entityName: "Recipe")
do {
let fetchedResults = try managedContext.fetch(fetchRequest)
if fetchedResults.count > 0 {
recipes = fetchedResults.map { ("\($0.recipeName)")}
return recipes
}
} catch let error as NSError {
// Wrong handling
print(error.description)
}
return recipes
}

Saving the right row in a TableView

I`m a Beginner in swift and i have tried to build a shopping list app with a tableView in it. Nearly everthing works, except:
When you reorder the rows, quit the app, and going back, the new row order was not saved.
Any ideas?
This is the important part:
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedObject = shoppingList[sourceIndexPath.row]
shoppingList.remove(at: sourceIndexPath.row)
shoppingList.insert(movedObject, at: destinationIndexPath.row)
}
But in will not work.....
Here is the whole code:
import UIKit
import CoreData
var shoppingList: [NSManagedObject] = [ ]
class ShoppingList_1: UIViewController, UITableViewDelegate,UITableViewDataSource {
//Anzahl Spalten -->
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
//**************************
//Zeilen: dynamisch; abhängig von Anzahl items in Liste -->
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return shoppingList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = shoppingList[indexPath.row]
let cell = Cell.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
// <-- Prototype Cell für Ausschnitt/Sicht des Bildschirms
cell.textLabel?.text = item.value(forKeyPath: "itemName") as? String
cell.detailTextLabel?.text = "\(indexPath.row)"
return cell
}
//free to use
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
print("Daten geladen!\n")
let movedObject = shoppingList[sourceIndexPath.row]
shoppingList.remove(at: sourceIndexPath.row)
shoppingList.insert(movedObject, at: destinationIndexPath.row)
NSLog("%#", "\(sourceIndexPath.row) => \(destinationIndexPath.row) \(shoppingList)")
// To check for correctness enable: self.tableView.reloadData()
}
//*****************************************************************************************************
//Durch wischen entfernen -->
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete
{
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
managedContext.delete(shoppingList[indexPath.row])
do {
try managedContext.save()
shoppingList.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
} catch let err as NSError {
print("12345", err)
}
}
}
#IBOutlet weak var AddButton: UIButton!
#IBOutlet weak var AddItem: UITextField!
#IBOutlet weak var Cell: UITableView!
#IBAction func EditTopRightButton(_ sender: UIBarButtonItem) {
self.Cell.isEditing = !self.Cell.isEditing
sender.title = (self.Cell.isEditing) ? "Done" : "Edit"
}
//Button Action
#IBAction func AddButton2_Test(_ sender: Any) {
print("My test")
let a:Float = 2
let b:Float = 3
let Ergebnis:Float = a+b
print(Ergebnis)
if (AddItem.text != "")
{
self.save(AddItem.text!)
}
Cell.reloadData()
}
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: "Item")
do {
shoppingList = try managedContext.fetch(fetchRequest)
} catch let err as NSError {
print("Failed to fetch items", err)
}
}
func save(_ itemName: String){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Item", in: managedContext)!
let item = NSManagedObject(entity: entity, insertInto: managedContext)
item.setValue(itemName, forKey: "itemName")
do {
try managedContext.save()
shoppingList.append(item)
} catch let err as NSError {
print("Failed to save item",err)
}
}
//*****************************************************************************************************
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Cell.delegate = self
Cell.dataSource = self
AddItem.delegate = self
}
//HINZU-->
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
//*****************************************************************************************************
// extensions -->
extension ShoppingList_1 : UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
AddItem.resignFirstResponder()
return true
}
}
//***************************************
Current Working
In your code, Table view is loaded with data from Coredata at viewWillAppear. Data inserted to core data is not updated when you change the order in TableView.
So even you changed order of cell and corder in Array. Every time viewWillAppear calls Data is again fetched from Coredata with no order.
ViewWillAppear will call every time view display in screen. Incase you are coming back to this view from any other presented view ViewWillAppear will call.
Sollution
You can create a new attribute in table describing order of item in Coredata Entity & Sort the item with this order after fetching.
Refer this answer to know how to set display order with core data
https://stackoverflow.com/a/31907857/4845644
Or If your requirement is just to persist order to ViewController instances existence you need to change core data fetch code from viewWillAppear to viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
Cell.delegate = self
Cell.dataSource = self
AddItem.delegate = self
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Item")
do {
shoppingList = try managedContext.fetch(fetchRequest)
} catch let err as NSError {
print("Failed to fetch items", err)
}
}

Value of type "Entity" has no member 'text'

I am making a basic note taking app. I cannot seem to change the text of my attributes in my code. Any advice?
import UIKit
import CoreData
class NoteInputTableViewController: UITableViewController, UINavigationControllerDelegate {
var listItem: List?
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
#IBOutlet weak var inputNoteLabel: UITextField!
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
if let item = listItem {
listItem.text = inputNoteLabel.text
} else {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("List", inManagedObjectContext: managedObjectContext) as! List
newItem.text = inputNoteLabel.text
}
if let controller = viewController as? NoteHomeTableViewController {
controller.items = [items!]
}
}
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
} // viewDidLoad end
}
In my navigationController I am attempting to change the text of my listItem, but cannot seem to do so.
Below is my List+CoreDataProperties.swift file:
import Foundation
import CoreData
extension List {
#NSManaged var note: String?
#NSManaged var completionDate: NSDate?
}
And below is my NoteHomeTableViewController.swift file:
import UIKit
import CoreData
class NoteHomeTableViewController: UITableViewController, MyCellDelegate { // will need a delegate
var items: [List] = []
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
#IBAction func composeButtonPressed(sender: UIBarButtonItem) {
performSegueWithIdentifier("CellDetailSegue", sender: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destination = segue.destinationViewController as! NoteInputTableViewController
if let ip = sender as? NSIndexPath {
destination.listItem = items[ip.row]
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("MyCell") as! MyCell
cell.indexPath = indexPath
cell.item = items[indexPath.row]
cell.delegate = self
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("CellDetailSegue", sender: indexPath)
}
func myCell(myCell: MyCell, didPressBackItem: List,
atIndexPath indexPath: NSIndexPath) {
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
let item = items[indexPath.row]
managedObjectContext.deleteObject(item)
do {
try managedObjectContext.save()
} catch {
print("error saving")
}
fetchItems()
tableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
} // viewDidLoad end
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
fetchItems()
tableView.reloadData()
} // viewDidAppear end
func fetchItems() {
let request = NSFetchRequest(entityName: "List")
items = []
do {
let response = try managedObjectContext.executeFetchRequest(request) as! [List]
for item in response {
items.append(item)
}
} catch {
print("Error fetching data!")
}
} // fetch end
} // class end
I don't see where you initialize listItem.
I suggest
} else {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("List", inManagedObjectContext: managedObjectContext) as! List
newItem.text = inputNoteLabel.text
}
should probably become
} else {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("List", inManagedObjectContext: managedObjectContext) as! List
listItem = newItem
newItem.text = inputNoteLabel.text
}
Use the unwrapped item after the optional binding and assign the new initialized NSManagedObject to listItem
...
if let item = listItem {
item.text = inputNoteLabel.text
} else {
listItem = NSEntityDescription.insertNewObjectForEntityForName("List", inManagedObjectContext: managedObjectContext) as! List
listItem!.text = inputNoteLabel.text
...
or easier
...
if listItem == nil {
listItem = NSEntityDescription.insertNewObjectForEntityForName("List", inManagedObjectContext: managedObjectContext) as! List
}
listItem!.text = inputNoteLabel.text
...

TableView definition conflict with previous using CoreData in Mutable array

I am trying to access the CoreData and putting it into the TableView so i have the data into the Mutable array but when i try to access it into the TableView then i got this error.
My code is as follows:
import UIKit
import CoreData
class TableView: UIViewController, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
var desc_arr: [String] = []
var amt_arr: [String] = []
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext
let request = NSFetchRequest(entityName: "Expense")
request.returnsObjectsAsFaults = false
do {
let results = try context.executeFetchRequest(request)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let desc = result.valueForKey("desc") as? String {
print(desc)
desc_arr.append(desc)
}
if let amt = result.valueForKey("amt") as? String{
print(amt)
amt_arr.append(amt)
}
}
}
} catch {
print("Fetch Failed")
}
print(desc_arr)
print(amt_arr)
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return desc_arr.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = desc_arr[indexPath.row]
return cell
}
}
}

Resources