Swift教程_CoreData实例(四)_构建控制层(查询、更新数据)_weixin_33829657的博客-程序员宅基地

技术标签: swift  

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
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33829657/article/details/90624840

智能推荐

使用“微pe工具”制作pe启动盘,安装纯净系统_微pe系统制作成功系统盘出入电脑显示是什么样的_IT农民哥的博客-程序员宅基地

网上制作pe的工具很多,像大白菜、老毛桃、u深度等等,但这些pe都有一个缺点,装好的系统多多少少都会给安装一些没必要的软件,此时还得一个个去删除。今天说的这款工具是一款纯净安装系统的工具,不会在安装好后自动装各种没用的软件。制作步骤如下:第一步,先下载。下载方法:1.输入下载地址:http://www.wepe.com.cn/2.点击下载,里面有各种版本,按照自己需求下载。3.点“我已捐赠”。凭自己意愿捐赠,没有捐赠也可以下载:4.进入以下微云下载界面,有不同版本,按照自己需求下载:第

html 字符画,字符画_weixin_39737947的博客-程序员宅基地

字符画,一种由字母、标点、汉字或其他字符组成的图画。简单的字符画是利用字符的形状代替图画的线条来构成简单的人物、事物等形象,它一般由人工制作而成;复杂的字符画通常利用占用不同数量像素的字符代替图画上不同明暗的点,它一般由程序制作而成。字符画是互联网时代的产物,通常应用于即时聊天中。中文名字符画所属学科IT所属领域技术应用领域绘画字符画关键技术编辑语音第一个关键技术:汉字库读取技术使用汉字库技术可以...

linux中/usr、/home、/bin、/dev、/var、/etc的区别_var和home_black_zt666的博客-程序员宅基地

linux中/etc是配置文件的目录,/var是储存各种变化的文件。特点:/etc的特点:包含了广泛的系统配置文件,这些配置文件几乎包含了系统配置的方方面面,是一个底层的重要项目,通常添加一些次等重要的零碎事物。/var的特点:包含系统运行时要改变的数据。其中包括每个系统是特定的,即不能够与其他计算机共享的目录。...

计算机图形学(二)输出图元_15_字符图元_heyuchang666的博客-程序员宅基地

和其他图元一样,字符的几何描述在世界坐标系中给出,该信息由观察变换映射到屏幕坐标系。位图字符使用矩形网格的二进制值及网格参考位置来描述。该位置随后被映射到帧缓存中的指定位置。轮廓字符由一组用曲线或线段连接的坐标位置和参考位置来定义,该参考位置随后也映射到给定的帧缓存位置。参考位置可用于一个字符或一个字符串。一般情况下,字符子程序可生成二维或三维字符显示。

504 Gateway Time-out解决方法_一步一步地往上爬的博客-程序员宅基地

504 Gateway Time-out就字面意思,我们可以理解为网页请求超时,也就是浏览网站网页所发出的请求没有反应或者未响应,在网站程序层面来说,就是请求未能够执行相应的PHP-CGI程序,或者PHP-CGI程序未能做出相应的处理,又或者是CGI程序的响应处理结果未能够反馈到浏览器或者未能及时反馈到浏览器。是由于nginx默认的fastcgi进程响应缓冲区太小造成: 这种情况下导致fast...

LaTeX中插入数学公式_latex公式导数_维博的博客-程序员宅基地

LaTeX中插入数学公式Posted on 2007-10-23 byLaTeX最强大的功能就是显示美丽的数学公式, 下面我们来看这些公式是怎么实现的.1、数学公式的前后要加上$或\(和\),比如:$f(x) = 3x + 7$和\(f(x) = 3x + 7\)效果是一样的;如果用\[和\],或者使用$$和$$,则改公式独占一行;如果用\begin

随便推点

异步上传文件报错,重复使用java流_jackson1024的博客-程序员宅基地

如果上传的时候,是同步上传的,不会出现问题。如果是异步上传的,如果你传入的异步方法是 MultipartFile file,就会包下面的错java.io.FileNotFoundException: D:\usr\local\tomcat\work\Tomcat\localhost\upload_46ba607a_d50c_4618_9b66_234953a0ba1f_00000002.tmp...

莫比乌斯函数_weixin_34370347的博客-程序员宅基地

在讲这个函数之前。最好先了解欧拉函数。我们用 \ 记为整除。 记得小学的时候整除和整除以的概念么?别混淆。 2整除4 记作 2\4。欧拉函数用来表示。那么根据法里级数的展开(这个感觉和ACM关系不大就先不介绍了。大概讲的就是构造所有最简分数的一种树。而法里级数n定义分母<=n的最简分数。)比如对于分母为12.化简后:分别为:1/12 1/6 1/...

Comparison of different SQL implementations(整理)_iteye_4537的博客-程序员宅基地

Comparison of different SQL implementationsThe goal of this page — which is a work in progress — is to gather information relevant for people who are porting SQL from one product to another and/...

串口/U(A/S)RT(RS232/RS485/RS422协议等)_urt串口_kuochu'ng的博客-程序员宅基地

串口就是URT。UART:universal asynchronous receiver and transmitter通用异步收发器;USART:universal synchronous asynchronous receiver and transmitter通用同步异步收发器。串口的通信协议一般是RS232。主要用在工业控制、路由器调试、串口通信。参考文章参考文章...

使用mathtype后,word自动生成目录中出现“Equation Chapter (Next) Section 1字样”_P0ny的博客-程序员宅基地

问题来源相信很多学生在写论文的时候会用用到很多的公式,不可避免的就要写公式的编号,真的是相当麻烦,如果你是手写的话。所以啊一般会在word 中使用mathtype的自动生成编号功能,具体怎么用呢:首先你创建一个章节断点,比如说你的公式序号形(1,2)(章节序号,本章内第几个公式)一般都会采用这种格式。所以你必须让mathtype知道这是第几章。比如说第二章的公式,你需要在第二章刚开始的地...

Code Jam Problem D. GoroSort_Hearthougan的博客-程序员宅基地

题目来源:https://code.google.com/codejam/contest/dashboard?c=975485#s=p3题目感觉非常不错,