Swift教程_CoreData实例(四)_构建控制层(查询、更新数据)

  1. 云栖社区>
  2. 博客>
  3. 正文

Swift教程_CoreData实例(四)_构建控制层(查询、更新数据)

ghost丶桃子 2016-05-19 16:23:01 浏览1703
展开阅读全文

Swift教程_CoreData实例(一)_构建storyboard

Swift教程_CoreData实例(二)_构建数据层

Swift教程_CoreData实例(三)_构建控制层(列表数据加载、删除数据)

Swift教程_CoreData实例(四)_构建控制层(查询、更新数据)

Swift教程_CoreData实例(五)_构建控制层(添加数据)

2.查询数据

我们自定义一个列表控制器PKOBookDetailTableViewController,并应用到storyboard的明细显示view中,用来显示所选中的book的明细。通过PKOBooksTableViewController传的Book对象来为列表赋值。
其中用到了监听系统语言变更通知的触发发放,以及coredata自带的undo、redo功能(撤销操作、取消撤销),当然不加这些功能也不影响最终效果,详细见代码与注释。
代码如下,注释非常详细,其中包含更新数据的部分代码,请结合下一小节的代码阅读:

[objc] view plain copy
  1. import UIKit  
  2.   
  3. class PKOBookDetailTableViewController: UITableViewController {  
  4.       
  5.     var book: Book!  
  6.       
  7.     @IBOutlet weak var titleLabel: UILabel!  
  8.     @IBOutlet weak var authorLabel: UILabel!  
  9.     @IBOutlet weak var dateLabel: UILabel!  
  10.       
  11.     //加载view时调用  
  12.     override func viewDidLoad() {  
  13.         super.viewDidLoad()  
  14.         NSLog("==viewDidLoad==")  
  15.           
  16.         self.navigationItem.rightBarButtonItem = self.editButtonItem()  
  17.           
  18.         //编辑的时候允许选择  
  19.         self.tableView.allowsSelectionDuringEditing = true  
  20.           
  21.         //监听到NSCurrentLocaleDidChangeNotification时,即系统语言变化时触发的方法,与removeObserver是一对  
  22.         NSNotificationCenter.defaultCenter().addObserver(self, selector"localeChanged:", name: NSCurrentLocaleDidChangeNotification, object: nil)  
  23.     }  
  24.       
  25.     //析构方法  
  26.     deinit{  
  27.         NSLog("==deinit==")  
  28.         NSNotificationCenter.defaultCenter().removeObserver(self, name: NSCurrentLocaleDidChangeNotification, object: nil)  
  29.     }  
  30.       
  31.       
  32.     /* 
  33.     The view controller must be first responder in order to be able to receive shake events for undo. It should resign first responder status when it disappears.指定是否可以时第一响应者,通俗来讲就是焦点 
  34.     */  
  35.     override func canBecomeFirstResponder() -> Bool {  
  36.         return true  
  37.     }  
  38.       
  39.     //view显示时设置焦点  
  40.     override func viewDidAppear(animated: Bool) {  
  41.         super.viewDidAppear(animated)  
  42.         self.becomeFirstResponder()  
  43.     }  
  44.       
  45.     //view销毁前取消焦点  
  46.     override func viewWillDisappear(animated: Bool) {  
  47.         super.viewWillDisappear(animated)  
  48.         self.resignFirstResponder()  
  49.     }  
  50.       
  51.     //视图即将可见时调用,每次显示view就会调用  
  52.     override func viewWillAppear(animated: Bool) {  
  53.         NSLog("==viewWillAppear==")  
  54.         super.viewWillAppear(animated)  
  55.           
  56.         //重载数据  
  57.         self.updateInterface()  
  58.         //改变右侧按钮状态  
  59.         self.updateRightBarButtonItemState()  
  60.     }  
  61.       
  62.     //设置为编辑模式时调用  
  63.     override func setEditing(editing: Bool, animated: Bool) {  
  64.         super.setEditing(editing, animated: animated)  
  65.         NSLog("==setEditing==\(editing)")  
  66.           
  67.         self.navigationItem.setHidesBackButton(editing, animated: animated)  
  68.           
  69.         //编辑状态时设置撤销管理器  
  70.         if(editing){  
  71.             self.setUpundoManager()  
  72.         }else  
  73.         //非编辑状态时取消撤销管理器并保存数据  
  74.         {  
  75.             self.cleanUpUndoManager()  
  76.             var error: NSError? = nil  
  77.             if (self.book.managedObjectContext?.save(&error) == nil) {  
  78.                 NSLog("Unresolved error \(error), \(error?.userInfo)")  
  79.                 abort()  
  80.             }  
  81.         }  
  82.     }  
  83.       
  84.     override func didReceiveMemoryWarning() {  
  85.         super.didReceiveMemoryWarning()  
  86.         // Dispose of any resources that can be recreated.  
  87.     }  
  88.       
  89.     //更新数据  
  90.     func updateInterface() {  
  91.         self.authorLabel.text = self.book.author  
  92.         self.titleLabel.text = self.book.title  
  93.         self.dateLabel.text = self.dateFormatter().stringFromDate(self.book.theDate)  
  94.     }  
  95.       
  96.     func updateRightBarButtonItemState() {  
  97.         NSLog("==updateRightBarButtonItemState==")  
  98.         // 如果实体对象在保存状态,则允许右侧按钮  
  99.         var error: NSError? = nil  
  100.         self.navigationItem.rightBarButtonItem?.enabled = self.book.validateForUpdate(&error)  
  101.     }  
  102.       
  103.       
  104.     // MARK: - Table view data source  
  105.       
  106.     //点击编辑按钮时的row编辑样式,默认delete,row前有一个删除标记,这里用none,没有任何标记  
  107.     override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {  
  108.         return UITableViewCellEditingStyle.None  
  109.     }  
  110.       
  111.     //点击编辑按钮时row是否需要缩进,这里不需要  
  112.     override func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool {  
  113.         return false  
  114.     }  
  115.       
  116.     //在行将要选择的时候执行。通常,你可以使用这个方法来阻止选定特定的行。返回结果是选择的行  
  117.     override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {  
  118.         if(self.editing){  
  119.             return indexPath  
  120.         }  
  121.         return nil  
  122.     }  
  123.       
  124.     //在选择行后执行,这里是编辑状态选中一行时创建一个编辑页面  
  125.     override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {  
  126.         if(self.editing){  
  127.             self.performSegueWithIdentifier("DetailToEdit", senderself)  
  128.         }  
  129.     }  
  130.       
  131.     // MARK: - Undo support  
  132.       
  133.     //设置撤回管理器  
  134.     func setUpundoManager() {  
  135.         if self.book.managedObjectContext?.undoManager == nil {  
  136.             self.book.managedObjectContext?.undoManager =  NSUndoManager()  
  137.             self.book.managedObjectContext?.undoManager?.levelsOfUndo = 3//撤销最大数  
  138.         }  
  139.           
  140.         var bookUndoManager = self.book.managedObjectContext?.undoManager  
  141.           
  142.         //监听撤回和取消撤回  
  143.         NSNotificationCenter.defaultCenter().addObserver(self, selector"undoManagerDidUndo:", name: NSUndoManagerDidUndoChangeNotification, object: bookUndoManager)  
  144.         NSNotificationCenter.defaultCenter().addObserver(self, selector"undoManagerDidRedo:", name: NSUndoManagerDidRedoChangeNotification, object: bookUndoManager)  
  145.     }  
  146.       
  147.     //取消撤回管理器  
  148.     func cleanUpUndoManager() {  
  149.         var bookUndoManager = self.book.managedObjectContext?.undoManager  
  150.           
  151.         //移除撤回和取消撤回监听  
  152.         NSNotificationCenter.defaultCenter().removeObserver(self, name: NSUndoManagerWillUndoChangeNotification, object: bookUndoManager)  
  153.         NSNotificationCenter.defaultCenter().removeObserver(self, name: NSUndoManagerWillRedoChangeNotification, object: bookUndoManager)  
  154.           
  155.         //置空context的撤回管理器  
  156.         self.book.managedObjectContext?.undoManager = nil  
  157.     }  
  158.       
  159.     //监听到撤回触发,重载数据和导航右侧按钮状态  
  160.     func undoManagerDidUndo(notification : NSNotification){  
  161.         NSLog("==undoManagerDidUndo==")  
  162.         //重载数据  
  163.         self.updateInterface()  
  164.         //改变右侧按钮状态  
  165.         self.updateRightBarButtonItemState()  
  166.     }  
  167.       
  168.     //监听到取消撤回触发,重载数据和导航右侧按钮状态  
  169.     func undoManagerDidRedo(notification : NSNotification){  
  170.         NSLog("==undoManagerDidRedo==")  
  171.         //重载数据  
  172.         self.updateInterface()  
  173.         //改变右侧按钮状态  
  174.         self.updateRightBarButtonItemState()  
  175.     }  
  176.       
  177.     // MARK: - Date Formatter  
  178.       
  179.     //日期格式化  
  180.     func dateFormatter() -> NSDateFormatter{  
  181.         var dateFormatter = NSDateFormatter()  
  182.         dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle  
  183.         dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle  
  184.         return dateFormatter  
  185.     }  
  186.       
  187.     // MARK: - Navigation  
  188.       
  189.     //通过segue跳转前所做的工作  
  190.     override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {  
  191.         if(segue.identifier == "DetailToEdit"){  
  192.             var bookEditViewController = segue.destinationViewController as PKOBookEditViewController  
  193.               
  194.             bookEditViewController.editedObject = self.book  
  195.             //根据选择的不同行为编辑view赋不同的值  
  196.             switch(self.tableView.indexPathForSelectedRow()!.row) {  
  197.             case 0:  
  198.                 bookEditViewController.editedFieldKey = "title"  
  199.                 bookEditViewController.editedFieldName = "title"  
  200.             case 1:  
  201.                 bookEditViewController.editedFieldKey = "author"  
  202.                 bookEditViewController.editedFieldName = "author"  
  203.             case 2:  
  204.                 bookEditViewController.editedFieldKey = "theDate"  
  205.                 bookEditViewController.editedFieldName = "theDate"  
  206.             default:  
  207.                 break  
  208.             }  
  209.         }  
  210.     }  
  211.       
  212.     // MARK: - Locale changes  
  213.       
  214.     //监听到语言变化时,重载数据  
  215.     func localeChanged(notification : NSNotification) {  
  216.         NSLog("==localeChanged==")  
  217.         //重载数据  
  218.         self.updateInterface()  
  219.     }  
  220.       
  221. }  

3.更新数据

我们自定义一个基本的view控制器PKOBookEditViewController,并应用到storyboard的编辑view中,用来编辑所选中的字段。通过PKOBookDetailTableViewController中所选择的字段为编辑view的字段赋值。
其中用到了日期选择控件,需要根据PKOBookDetailTableViewController选择的字段来判断显示哪种控件。
代码如下,注释非常详细:

[objc] view plain copy
  1. import UIKit  
  2.   
  3. class PKOBookEditViewController: UIViewController {  
  4.   
  5.     @IBOutlet weak var textField: UITextField!  
  6.     @IBOutlet weak var datePicker: UIDatePicker!  
  7.     var editedObject: Book!  
  8.     var editedFieldKey: String!  
  9.     var editedFieldName: String!  
  10.     var editingDate: Bool!{  
  11.         get{  
  12.             //判断是否是日期字段  
  13.             var attributeClassName = self.editedObject.entity.attributesByName[self.editedFieldKey]?.attributeValueClassName?  
  14.             if attributeClassName == "NSDate" {  
  15.                 return true  
  16.             }  
  17.             else {  
  18.                 return false  
  19.             }  
  20.         }  
  21.     }  
  22.       
  23.     override func viewDidLoad() {  
  24.         super.viewDidLoad()  
  25.         //为标题赋值  
  26.         self.title = self.editedFieldName  
  27.         //如果选中日期,则显示日期控件  
  28.         if self.editingDate! {  
  29.             self.textField.hidden = true  
  30.             self.datePicker.hidden = false  
  31.               
  32.             var date = self.editedObject.valueForKey(self.editedFieldKey) as? NSDate  
  33.             if date == nil {  
  34.                 date = NSDate()  
  35.             }  
  36.             self.datePicker.date = date!  
  37.         }  
  38.         else {  
  39.             self.textField.hidden = false  
  40.             self.datePicker.hidden = true  
  41.             self.textField.text = self.editedObject.valueForKey(self.editedFieldKey) as String  
  42.             self.textField.placeholder = self.title//空的时候显示值  
  43.             self.textField.becomeFirstResponder()  
  44.         }  
  45.     }  
  46.   
  47.     override func didReceiveMemoryWarning() {  
  48.         super.didReceiveMemoryWarning()  
  49.         // Dispose of any resources that can be recreated.  
  50.     }  
  51.       
  52.     //点击保存  
  53.     @IBAction func saveAction(sender: AnyObject) {  
  54.         // Set the action name for the undo operation.给撤回操作设置name  
  55.         NSLog("==saveAction==\(self.editedFieldName)")  
  56.         var undoManager = self.editedObject.managedObjectContext?.undoManager  
  57.         undoManager?.setActionName(self.editedFieldName)  
  58.           
  59.         //更新该对象,然后抛出  
  60.         if self.editingDate! {  
  61.             self.editedObject.setValue(self.datePicker.date, forKey:self.editedFieldKey)  
  62.         }  
  63.         else {  
  64.             self.editedObject.setValue(self.textField.text, forKey:self.editedFieldKey)  
  65.         }  
  66.           
  67.         self.navigationController?.popViewControllerAnimated(true)  
  68.     }  
  69.   
  70. }  

原文地址:http://blog.csdn.net/ooppookid/article/details/40887317

网友评论

登录后评论
0/500
评论