UI TableView 单元格使用 swift 中的核心数据打开包含多个数据的新视图
UI TableView cell opening a new view with multiple data using coredata in swift
作为 iOS 和 Swift 的初学者,我有一个项目必须有一个包含多个单元格的 table 视图,其中每个单元格都包含多种数据类型。即字符串、日期等,在一个视图控制器中,有 table 视图用于查看单元格,第二个视图控制器用于创建单元格并输入数据,第三个视图用于显示相同的内容单击单元格时的数据。我决定使用 coredata 存储所有这些,因为有人告诉我它对初学者来说是最有效和最简单的。我已经使用了几个关于这个问题的教程,但其中 none 处理了我遇到的这类问题。最好的例子是 联系人列表 如何在 iOS 上工作。
到目前为止我完成的代码是这样的:
var titleCellList = [NSManagedObject]()
var infoCellList = [NSManagedObject]()
class CellsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var cellsTableView: UITableView!
//MARK: Default Functions
override func viewDidLoad() {
super.viewDidLoad()
title = "\"Lists\""
cellsTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
// Do any additional setup after loading the view.
}
// 标记:UITableViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TitleCellList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell
let cellTitle = titleCellList[indexPath.row]
cell.textLabel!.text = cellTitle.valueForKey("title") as? String
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(animated: Bool) {
cellsTableView.reloadData()
}
//标记:存储核心数据
func saveName(name: String) {
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let entity = NSEntityDescription.entityForName("Data", inManagedObjectContext: managedContext)
let title = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
//3
title.setValue(name, forKey: "title")
//4
var error: NSError?
if !managedContext.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
//5
titleCellList.append(title)
}
//标记:获取核心数据
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let fetchRequest = NSFetchRequest(entityName:"Data")
//3
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject]
if let results = fetchedResults {
titleCellList = results
} else {
println("Could not fetch \(error), \(error!.userInfo)")
}
}
// 标记:Table 编辑方法
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext!
context.deleteObject(titleCellList[indexPath.row] as NSManagedObject)
titleCellList.removeAtIndex(indexPath.row)
context.save(nil)
cellsTableView.reloadData()
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
println("Row: \(row)")
println(titleCellList[row])
performSegueWithIdentifier("checkCellSegue", sender: self)
}
第二个视图控制器(用于创建带有数据的单元格的那个)
class AddNewViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var titleTextField: UITextField!
@IBOutlet var shortInfoTextView: UITextView!
//MARK: Default Functions
override func viewDidLoad() {
super.viewDidLoad()
self.titleTextField.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
@IBAction func addDataButtonPressed(sender: UIButton) {
if titleTextField.text != "" {
CellsViewController().saveName(titleTextField.text)
titleTextField.text = ""
shortInfoTextView.text = ""
println("New title Added!")
}else {
println("No empty titles allowed!")
}
}
现在,此代码的大部分来自教程,当我尝试添加其他数据实体时,它不起作用。在数据模型中,我目前只有 1 个名为 "Data" 的实体,其中包含 4 个模型。因此,总而言之,我需要在一个实体中存储 4 个数据模型,并在单击一个单元格时将它们加载到不同的视图控制器上,当然,该单元格具有用户编写的标题。请注意,我花了几个小时在网上搜索答案,所以这是我的最后一句话。
如有任何帮助,我们将不胜感激。
所以,这是我在这个小问题上使用的一种方法。我基本上只是用 prepareForSegue 方法传递参数,在它里面我只是传递我想在另一个 class/VC.
中使用的数据
代码:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
// Setter for Second VC, destination path --> var declarations in Second VC
if segue.identifier == "checkCellSegue" {
let destination = segue.destinationViewController as! SecondViewController
if let indexPath = self.tableView?.indexPathForCell(sender as! UITableViewCell) {
let object = fetchedResultsController?.objectAtIndexPath(indexPath) as? Data
destination.cellTitle = object?.cellTitle
destination.textViewInfo = object?.textViewInfo
destination.timerValue = object?.timerValue
}
}
因此,首先我们声明目的地,这是我们的第二个 VC 的名称或任何您命名的名称。然后,由于我通过 TableView 单元格访问数据,我们需要使用 indexPath 获取我的 CoreData 实体。之后,最终声明是模型 Class,它具有来自实体的所有数据值,它将像单例一样工作。
destination.cellTitle // --> in the 2.nd VC we declared a new var called cellTitle, var cellTitle:String
object?.cellTitle // --> in the model class "Data.swift" the declaration is @NSManaged var cellTitle:String
所以,就是这样。我在iOS上还是个小菜鸟,所以如果有任何错误,请尽管说。
作为 iOS 和 Swift 的初学者,我有一个项目必须有一个包含多个单元格的 table 视图,其中每个单元格都包含多种数据类型。即字符串、日期等,在一个视图控制器中,有 table 视图用于查看单元格,第二个视图控制器用于创建单元格并输入数据,第三个视图用于显示相同的内容单击单元格时的数据。我决定使用 coredata 存储所有这些,因为有人告诉我它对初学者来说是最有效和最简单的。我已经使用了几个关于这个问题的教程,但其中 none 处理了我遇到的这类问题。最好的例子是 联系人列表 如何在 iOS 上工作。 到目前为止我完成的代码是这样的:
var titleCellList = [NSManagedObject]()
var infoCellList = [NSManagedObject]()
class CellsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var cellsTableView: UITableView!
//MARK: Default Functions
override func viewDidLoad() {
super.viewDidLoad()
title = "\"Lists\""
cellsTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
// Do any additional setup after loading the view.
}
// 标记:UITableViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TitleCellList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell
let cellTitle = titleCellList[indexPath.row]
cell.textLabel!.text = cellTitle.valueForKey("title") as? String
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(animated: Bool) {
cellsTableView.reloadData()
}
//标记:存储核心数据
func saveName(name: String) {
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let entity = NSEntityDescription.entityForName("Data", inManagedObjectContext: managedContext)
let title = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
//3
title.setValue(name, forKey: "title")
//4
var error: NSError?
if !managedContext.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
//5
titleCellList.append(title)
}
//标记:获取核心数据
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let fetchRequest = NSFetchRequest(entityName:"Data")
//3
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject]
if let results = fetchedResults {
titleCellList = results
} else {
println("Could not fetch \(error), \(error!.userInfo)")
}
}
// 标记:Table 编辑方法
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext!
context.deleteObject(titleCellList[indexPath.row] as NSManagedObject)
titleCellList.removeAtIndex(indexPath.row)
context.save(nil)
cellsTableView.reloadData()
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
println("Row: \(row)")
println(titleCellList[row])
performSegueWithIdentifier("checkCellSegue", sender: self)
}
第二个视图控制器(用于创建带有数据的单元格的那个)
class AddNewViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var titleTextField: UITextField!
@IBOutlet var shortInfoTextView: UITextView!
//MARK: Default Functions
override func viewDidLoad() {
super.viewDidLoad()
self.titleTextField.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
@IBAction func addDataButtonPressed(sender: UIButton) {
if titleTextField.text != "" {
CellsViewController().saveName(titleTextField.text)
titleTextField.text = ""
shortInfoTextView.text = ""
println("New title Added!")
}else {
println("No empty titles allowed!")
}
}
现在,此代码的大部分来自教程,当我尝试添加其他数据实体时,它不起作用。在数据模型中,我目前只有 1 个名为 "Data" 的实体,其中包含 4 个模型。因此,总而言之,我需要在一个实体中存储 4 个数据模型,并在单击一个单元格时将它们加载到不同的视图控制器上,当然,该单元格具有用户编写的标题。请注意,我花了几个小时在网上搜索答案,所以这是我的最后一句话。
如有任何帮助,我们将不胜感激。
所以,这是我在这个小问题上使用的一种方法。我基本上只是用 prepareForSegue 方法传递参数,在它里面我只是传递我想在另一个 class/VC.
中使用的数据代码:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
// Setter for Second VC, destination path --> var declarations in Second VC
if segue.identifier == "checkCellSegue" {
let destination = segue.destinationViewController as! SecondViewController
if let indexPath = self.tableView?.indexPathForCell(sender as! UITableViewCell) {
let object = fetchedResultsController?.objectAtIndexPath(indexPath) as? Data
destination.cellTitle = object?.cellTitle
destination.textViewInfo = object?.textViewInfo
destination.timerValue = object?.timerValue
}
}
因此,首先我们声明目的地,这是我们的第二个 VC 的名称或任何您命名的名称。然后,由于我通过 TableView 单元格访问数据,我们需要使用 indexPath 获取我的 CoreData 实体。之后,最终声明是模型 Class,它具有来自实体的所有数据值,它将像单例一样工作。
destination.cellTitle // --> in the 2.nd VC we declared a new var called cellTitle, var cellTitle:String
object?.cellTitle // --> in the model class "Data.swift" the declaration is @NSManaged var cellTitle:String
所以,就是这样。我在iOS上还是个小菜鸟,所以如果有任何错误,请尽管说。