<a target="_blank" href="http://write.blog.csdn.net/postedit/40661957">swift教程_coredata实例(一)_构建storyboard</a>
<a target="_blank" href="http://blog.csdn.net/ooppookid/article/details/40867835">swift教程_coredata实例(三)_构建控制层(列表数据加载、删除数据)</a>
swift教程_coredata实例(四)_构建控制层(查询、更新数据)
<a target="_blank" href="http://blog.csdn.net/ooppookid/article/details/41149291">swift教程_coredata实例(五)_构建控制层(添加数据)</a>
我们自定义一个列表控制器pkobookdetailtableviewcontroller,并应用到storyboard的明细显示view中,用来显示所选中的book的明细。通过pkobookstableviewcontroller传的book对象来为列表赋值。
其中用到了监听系统语言变更通知的触发发放,以及coredata自带的undo、redo功能(撤销操作、取消撤销),当然不加这些功能也不影响最终效果,详细见代码与注释。
代码如下,注释非常详细,其中包含更新数据的部分代码,请结合下一小节的代码阅读:
import uikit
class pkobookdetailtableviewcontroller: uitableviewcontroller {
var book: book!
@iboutlet weak var titlelabel: uilabel!
@iboutlet weak var authorlabel: uilabel!
@iboutlet weak var datelabel: uilabel!
//加载view时调用
override func viewdidload() {
super.viewdidload()
nslog("==viewdidload==")
self.navigationitem.rightbarbuttonitem = self.editbuttonitem()
//编辑的时候允许选择
self.tableview.allowsselectionduringediting = true
//监听到nscurrentlocaledidchangenotification时,即系统语言变化时触发的方法,与removeobserver是一对
nsnotificationcenter.defaultcenter().addobserver(self, selector: "localechanged:", name: nscurrentlocaledidchangenotification, object: nil)
}
//析构方法
deinit{
nslog("==deinit==")
nsnotificationcenter.defaultcenter().removeobserver(self, name: nscurrentlocaledidchangenotification, object: nil)
/*
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.指定是否可以时第一响应者,通俗来讲就是焦点
*/
override func canbecomefirstresponder() -> bool {
return true
//view显示时设置焦点
override func viewdidappear(animated: bool) {
super.viewdidappear(animated)
self.becomefirstresponder()
//view销毁前取消焦点
override func viewwilldisappear(animated: bool) {
super.viewwilldisappear(animated)
self.resignfirstresponder()
//视图即将可见时调用,每次显示view就会调用
override func viewwillappear(animated: bool) {
nslog("==viewwillappear==")
super.viewwillappear(animated)
//重载数据
self.updateinterface()
//改变右侧按钮状态
self.updaterightbarbuttonitemstate()
//设置为编辑模式时调用
override func setediting(editing: bool, animated: bool) {
super.setediting(editing, animated: animated)
nslog("==setediting==\(editing)")
self.navigationitem.sethidesbackbutton(editing, animated: animated)
//编辑状态时设置撤销管理器
if(editing){
self.setupundomanager()
}else
//非编辑状态时取消撤销管理器并保存数据
{
self.cleanupundomanager()
var error: nserror? = nil
if (self.book.managedobjectcontext?.save(&error) == nil) {
nslog("unresolved error \(error), \(error?.userinfo)")
abort()
}
}
override func didreceivememorywarning() {
super.didreceivememorywarning()
// dispose of any resources that can be recreated.
//更新数据
func updateinterface() {
self.authorlabel.text = self.book.author
self.titlelabel.text = self.book.title
self.datelabel.text = self.dateformatter().stringfromdate(self.book.thedate)
func updaterightbarbuttonitemstate() {
nslog("==updaterightbarbuttonitemstate==")
// 如果实体对象在保存状态,则允许右侧按钮
var error: nserror? = nil
self.navigationitem.rightbarbuttonitem?.enabled = self.book.validateforupdate(&error)
// mark: - table view data source
//点击编辑按钮时的row编辑样式,默认delete,row前有一个删除标记,这里用none,没有任何标记
override func tableview(tableview: uitableview, editingstyleforrowatindexpath indexpath: nsindexpath) -> uitableviewcelleditingstyle {
return uitableviewcelleditingstyle.none
//点击编辑按钮时row是否需要缩进,这里不需要
override func tableview(tableview: uitableview, shouldindentwhileeditingrowatindexpath indexpath: nsindexpath) -> bool {
return false
//在行将要选择的时候执行。通常,你可以使用这个方法来阻止选定特定的行。返回结果是选择的行
override func tableview(tableview: uitableview, willselectrowatindexpath indexpath: nsindexpath) -> nsindexpath? {
if(self.editing){
return indexpath
return nil
//在选择行后执行,这里是编辑状态选中一行时创建一个编辑页面
override func tableview(tableview: uitableview, didselectrowatindexpath indexpath: nsindexpath) {
self.performseguewithidentifier("detailtoedit", sender: self)
// mark: - undo support
//设置撤回管理器
func setupundomanager() {
if self.book.managedobjectcontext?.undomanager == nil {
self.book.managedobjectcontext?.undomanager = nsundomanager()
self.book.managedobjectcontext?.undomanager?.levelsofundo = 3//撤销最大数
var bookundomanager = self.book.managedobjectcontext?.undomanager
//监听撤回和取消撤回
nsnotificationcenter.defaultcenter().addobserver(self, selector: "undomanagerdidundo:", name: nsundomanagerdidundochangenotification, object: bookundomanager)
nsnotificationcenter.defaultcenter().addobserver(self, selector: "undomanagerdidredo:", name: nsundomanagerdidredochangenotification, object: bookundomanager)
//取消撤回管理器
func cleanupundomanager() {
//移除撤回和取消撤回监听
nsnotificationcenter.defaultcenter().removeobserver(self, name: nsundomanagerwillundochangenotification, object: bookundomanager)
nsnotificationcenter.defaultcenter().removeobserver(self, name: nsundomanagerwillredochangenotification, object: bookundomanager)
//置空context的撤回管理器
self.book.managedobjectcontext?.undomanager = nil
//监听到撤回触发,重载数据和导航右侧按钮状态
func undomanagerdidundo(notification : nsnotification){
nslog("==undomanagerdidundo==")
//监听到取消撤回触发,重载数据和导航右侧按钮状态
func undomanagerdidredo(notification : nsnotification){
nslog("==undomanagerdidredo==")
// mark: - date formatter
//日期格式化
func dateformatter() -> nsdateformatter{
var dateformatter = nsdateformatter()
dateformatter.datestyle = nsdateformatterstyle.shortstyle
dateformatter.timestyle = nsdateformatterstyle.nostyle
return dateformatter
// mark: - navigation
//通过segue跳转前所做的工作
override func prepareforsegue(segue: uistoryboardsegue, sender: anyobject?) {
if(segue.identifier == "detailtoedit"){
var bookeditviewcontroller = segue.destinationviewcontroller as pkobookeditviewcontroller
bookeditviewcontroller.editedobject = self.book
//根据选择的不同行为编辑view赋不同的值
switch(self.tableview.indexpathforselectedrow()!.row) {
case 0:
bookeditviewcontroller.editedfieldkey = "title"
bookeditviewcontroller.editedfieldname = "title"
case 1:
bookeditviewcontroller.editedfieldkey = "author"
bookeditviewcontroller.editedfieldname = "author"
case 2:
bookeditviewcontroller.editedfieldkey = "thedate"
bookeditviewcontroller.editedfieldname = "thedate"
default:
break
// mark: - locale changes
//监听到语言变化时,重载数据
func localechanged(notification : nsnotification) {
nslog("==localechanged==")
}
我们自定义一个基本的view控制器pkobookeditviewcontroller,并应用到storyboard的编辑view中,用来编辑所选中的字段。通过pkobookdetailtableviewcontroller中所选择的字段为编辑view的字段赋值。
其中用到了日期选择控件,需要根据pkobookdetailtableviewcontroller选择的字段来判断显示哪种控件。
代码如下,注释非常详细:
class pkobookeditviewcontroller: uiviewcontroller {
@iboutlet weak var textfield: uitextfield!
@iboutlet weak var datepicker: uidatepicker!
var editedobject: book!
var editedfieldkey: string!
var editedfieldname: string!
var editingdate: bool!{
get{
//判断是否是日期字段
var attributeclassname = self.editedobject.entity.attributesbyname[self.editedfieldkey]?.attributevalueclassname?
if attributeclassname == "nsdate" {
return true
else {
return false
//为标题赋值
self.title = self.editedfieldname
//如果选中日期,则显示日期控件
if self.editingdate! {
self.textfield.hidden = true
self.datepicker.hidden = false
var date = self.editedobject.valueforkey(self.editedfieldkey) as? nsdate
if date == nil {
date = nsdate()
self.datepicker.date = date!
else {
self.textfield.hidden = false
self.datepicker.hidden = true
self.textfield.text = self.editedobject.valueforkey(self.editedfieldkey) as string
self.textfield.placeholder = self.title//空的时候显示值
self.textfield.becomefirstresponder()
//点击保存
@ibaction func saveaction(sender: anyobject) {
// set the action name for the undo operation.给撤回操作设置name
nslog("==saveaction==\(self.editedfieldname)")
var undomanager = self.editedobject.managedobjectcontext?.undomanager
undomanager?.setactionname(self.editedfieldname)
//更新该对象,然后抛出
self.editedobject.setvalue(self.datepicker.date, forkey:self.editedfieldkey)
self.editedobject.setvalue(self.textfield.text, forkey:self.editedfieldkey)
self.navigationcontroller?.popviewcontrolleranimated(true)
原文地址:http://blog.csdn.net/ooppookid/article/details/40887317