Swift语言学习---------高级之简单通讯录制作
效果图:
文件目录:
示例代码如下:
Contact.swift
import UIKit
class Contact: NSObject {
//声明属性
var name:String?
var phone:String?
var gender:String?
var age:String?
//初始化方法
init(name:String ,phone:String,gender:String,age:String){
self.name = name
self.phone = phone
self.gender = gender
self.age = age
}
}
DataHelper.swift
import UIKit
class DataHelper: NSObject {
//谨记:在Swift中创建单例对象
static let shareInstance:DataHelper = DataHelper()
//声明一个数组属性,用来存放所有联系人
var modelArray:Array = Array<Contact>()
//声明数据处理的方法
//1.向数组中添加联系人
func addContact(contact:Contact){
modelArray.append(contact)
}
//2.从数组中移除一个联系人
func deleteContactWithPath(indeaPath:NSIndexPath){
modelArray.removeAtIndex(indeaPath.row)
}
//3.获取有多少个联系人
func countOfModels()->Int{
return modelArray.count
}
//4.根据indexPath 查找某个联系人
func getContactWithIndexPath(indexPath:NSIndexPath)->Contact{
return modelArray[indexPath.row]
}
//5.根据fromIndexPath和ToIndexPath实现元素的移动
func moveContact(fromIndexPath:NSIndexPath,toIndexPath:NSIndexPath){
let contact = modelArray[fromIndexPath.row]
//先更新数据源,想要移动先删除对应位置元素,然后再插入一个元素
modelArray.removeAtIndex(fromIndexPath.row)
modelArray.insert(contact,atIndex: toIndexPath.row)
}
}
contactCell.swift
import UIKit
class contactCell: UITableViewCell {
//'!'表示只取里面的值
@IBOutlet var nameLabel: UILabel!
@IBOutlet var phoneLabel: UILabel!
@IBOutlet var genderLabel: UILabel!
@IBOutlet var ageLabel: UILabel!
//声明一个计算属性的方法 !/?表示必须有值
//contact这里声明为计算属性
var contact:Contact!{
get{
return nil
}
set{
//会自动创建一个newValue作为参数,接收外部传过来的对象
nameLabel.text = newValue?.name
phoneLabel.text = newValue?.phone
genderLabel.text = newValue?.gender
ageLabel.text = newValue?.age
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
ComtactLiatTableViewController.swift
import UIKit
class ComtactLiatTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = self.editButtonItem()
//注册cell (使用StroyBoard必须注册cell)
self.tableView.registerNib(UINib(nibName: "contactCell", bundle: nil), forCellReuseIdentifier: "cell")
//创建联系人对象
let contact:Contact = Contact(name: "张三", phone: "123", gender: "男", age: "20")
//将联系人添加到数组中
DataHelper.shareInstance.addContact(contact)
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//计算有多少行
return DataHelper.shareInstance.countOfModels()
}
//override为继承父类的方法
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//这里用到了强转 as!contactCell强转的标志
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)as!contactCell
//获取某个联系人对象
let contact:Contact = DataHelper.shareInstance.getContactWithIndexPath(indexPath)
//设置cell
// cell.nameLabel.text = contact.name
//设置models的赋值过程
cell.contact = contact
return cell
}
//点击cell时,实现的方法
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//根据storyBoardID获取 storyboard中的某个视图控制器
//as!ContactDetailViewController 这里使用了强制类型转化
let detailVC = self.storyboard?.instantiateViewControllerWithIdentifier("DetailVC")as!ContactDetailViewController
//根据indexPath获取contact对象
//使用单例添加联系人
let contact = DataHelper.shareInstance.getContactWithIndexPath(indexPath)
//属性传值
detailVC.contact = contact
//push到下一个页面
self.navigationController?.pushViewController(detailVC, animated: true)
}
//cell是否处于编辑状态,返回值为Bool类型
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
// 提交编辑类型 (是删除还是添加)
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
//删除数据 调用单例的方法
DataHelper.shareInstance.deleteContactWithPath(indexPath)
//删除UI (先更新数据源,再更新UI界面)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
//cell移动的方法
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
//在单例类中已经声明了相关的方法
DataHelper.shareInstance.moveContact(fromIndexPath, toIndexPath: toIndexPath)
}
//cell是否移动返回值为Bool类型
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
//cell所在行的内部设置
let action1 = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "取消关注") { (action:UITableViewRowAction, indexPath:NSIndexPath) -> Void in
print("点击了取消关注按钮会取消")
}
let action2 = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "标记为已读") { (action:UITableViewRowAction, indexPath:NSIndexPath) -> Void in
print("点击了标记为已读按钮会取消标记")
}
//返回
return[action1,action2]
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//as!AddContactViewController 强制类型转化标识
let NC = segue.destinationViewController as!UINavigationController
let addContactVC = NC.viewControllers.first as!AddContactViewController
//闭包的实现部分 利用闭包实现tabelView的页面刷新
addContactVC.block = {
Back in
self.tableView.reloadData()
}
}
}
ContactDetailViewController.swift
import UIKit
class ContactDetailViewController: UIViewController {
@IBOutlet var nameLabel: UILabel!
@IBOutlet var phoneLabel: UILabel!
@IBOutlet var genderLabel: UILabel!
@IBOutlet var ageLabel: UILabel!
//声明存储属性(详情展示页面使用存储属性是因为程序在执行过程中所具有的先后顺序
var contact:Contact? //后面'?'如果不给这个属性赋值系统会默认给这个属性一个值,如果不使用'?'就必须手动给其一个值
override func viewDidLoad() {
super.viewDidLoad()
nameLabel.text = contact!.name
phoneLabel.text = contact!.phone
genderLabel.text = contact!.gender
ageLabel.text = contact!.age
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
AddContactViewController.swift
import UIKit
//类型重定义
typealias Back = () ->Void
//其中()->void是就类型, back给旧类型重新其的名字
class AddContactViewController: UIViewController {
//声明闭包
var block:(Back)?
@IBOutlet var nameTextField: UITextField!
@IBOutlet var phoneTextField: UITextField!
@IBOutlet var genderTextField: UITextField!
@IBOutlet var ageTextField: UITextField!
@IBAction func didClickDoneBI(sender: AnyObject) {
//1.将填写的数据封装成contact对象 用
let contact:Contact = Contact(name:nameTextField.text!, phone: phoneTextField.text!, gender: genderTextField.text!, age: ageTextField.text!)
//保存数据
DataHelper.shareInstance.addContact(contact)
//调用闭包让列表页面进行刷新
block!()
//返回到列表页面
dismissViewControllerAnimated(true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}