1.(新建文件)
ContactListTableViewController.swift:
2. 定义UITableView的视图 :class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
//2
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let firstLetter = "宋仲基".uppercasePinYinFirstLetter()
print(firstLetter!)
// print(ContactManager.sharecontactManager)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.backgroundColor = #colorLiteral(red: 0.2588235438, green: 0.7568627596, blue: 0.9686274529, alpha: 1)
self.window?.makeKeyAndVisible()
//创建导航视图控制器的根视图
let vc = ContactListTableViewController()
//2.创建导航视图控制器,并为她制定根视图控制器
let navigation = UINavigationController(rootViewController: vc)
//3.将导航视图控制器设置为window的根视图控制器
self.window?.rootViewController = navigation
return true
}
3. (新建添加联系人视图) addContactViewController.swift
4.(新建详情界面)DetailViewController.swift
5.Contact.swift:)(新建类)
//5
class Contact: NSObject {
var name:String!
var phone:String!
var adress:String!
var image:UIImage?
init(name:String,phone:String,adress:String,image:UIImage?) {
self.name = name
self.phone = phone
self.adress = adress
self.image = image
}
override init() {
super.init()
}
}
6.ContactManager.swift(新建单例类)
//7
#import “pinyin.h”(将拼音文件拖到工程里,在蓝色头文件Build Setting中搜索bridg找到Objective - C Bridging Header将新建文件Header的路径拖到后面的点击出来的空白处 然后引入头文件)
ContactManager.swift:
class ContactManager: NSObject {
//8
//创建一个单例属性
static let share = ContactManager()
//9
//数组初始化
var dataSource:[String:[Contact]] = Dictionary()
//10
//添加一个key的数组
var keys:[String] = Array()
//11
//添加联系人的方法
func addcontact(acontact:Contact) {
//两种情况:联系人的分组存在,直接根据分组名取出
let name = acontact.name
let firstLetter = name?.uppercasePinYinFirstLetter()
var group = dataSource[firstLetter!]
if group == nil {
//不存在
//初始化数组
group = Array()
group?.append(acontact)
//添加value值
keys.append(firstLetter!)
keys.sort()
}
else{
group?.append(acontact)
}
//对字典赋值
dataSource[firstLetter!] = group
}
// 12
//返回分区
func numberofSection()->Int{
return dataSource.count
}
//13
//返回分区中cell的个数
func numberofRowsInSection(section:Int)->Int{
let key = keys[section]
let group = dataSource[key]
return (group?.count)!
}
//14
func contacshowByIndexPath(indexpath:IndexPath) -> Contact {
let key = keys[indexpath.section]
let group = dataSource[key]
//返回要展示cell联系人对象的方法
return group![indexpath.row]
}
//15
func sectionHeaderTitle(section:Int) -> String {
return keys[section]
}
//16
func Sectiontitle()->[String]{
return keys
}
ContactListTableViewController.swift:
class ContactListTableViewController: UITableViewController {
//17
let systemCell = "cell"
override func viewDidLoad() {
super.viewDidLoad()
//18
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: systemCell)
self.SetnavigationItem()
//30
self.navigationItem.rightBarButtonItem = self.editButtonItem
}
//19
func SetnavigationItem(){
self.navigationController?.navigationItem.rightBarButtonItem = self.editButtonItem
self.title = "通讯录"
//设置navigation的字体大小和颜色
let dic = [NSFontAttributeName:UIFont.systemFont(ofSize: 30.0),NSForegroundColorAttributeName:UIColor.red]
self.navigationController?.navigationBar.titleTextAttributes = dic
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addContactAction))
}
//20
override func viewWillAppear(_ animated: Bool) {
self.tableView.reloadData()
}
//21
func addContactAction(){
//模态添加联系人
//22
let addContactVC = addContactViewController()
let rootVC = UINavigationController(rootViewController: addContactVC)
self.present(rootVC, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
//23
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return ContactManager.share.numberofSection()
}
//24
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return ContactManager.share.numberofRowsInSection(section: section)
}
/**/
//25
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: systemCell, for: indexPath)
cell.backgroundColor = UIColor.yellow
//26
let acontact = ContactManager.share.contacshowByIndexPath(indexpath: indexPath)
//51
//单例调用返回联系人的方法
cell.imageView?.image = acontact.image
cell.textLabel?.text = acontact.name
cell.detailTextLabel?.text = acontact.phone
return cell
}
//27
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return ContactManager.share.sectionHeaderTitle(section: section)
}
//28
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return ContactManager.share.Sectiontitle()
}
//29
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let detailVC = DetailViewController()
//2...
detailVC.acontact = ContactManager.share.contacshowByIndexPath(indexpath: indexPath)
self.navigationController?.pushViewController(detailVC, animated: true)
}
addContactViewController.swift:
class addContactViewController: UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate {
//31
var photaView:UIImageView!
var nameField:UITextField!
var photoField:UITextField!
var addressTexView:UITextView!
override func viewDidLoad() {
super.viewDidLoad()
self.setupViews()
self.SetNavigationItem()
}
//32
func setupViews() {
//图片
photaView = UIImageView(frame: CGRect(x: 132, y: 80, width: 150, height: 150))
photaView.backgroundColor = UIColor.cyan
self.view.addSubview(photaView)
//36
let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction))
photaView.isUserInteractionEnabled = true
photaView.addGestureRecognizer(tap)
//姓名
nameField = UITextField(frame: CGRect(x: 107, y: 240, width: 200, height: 40))
nameField.placeholder = "输入姓名"
nameField.borderStyle = .roundedRect
self.view.addSubview(nameField)
//电话
photoField = UITextField(frame: CGRect(x: 107, y: 290, width: 200, height: 40))
photoField.placeholder = "输入电话"
photoField.borderStyle = .roundedRect
self.view.addSubview(photoField)
//住址
addressTexView = UITextView(frame: CGRect(x: 107, y: 340, width: 200, height: 120))
addressTexView.text = "地址:"
addressTexView.layer.borderWidth = 1.0
addressTexView.layer.borderColor = UIColor.red.cgColor
self.view.addSubview(addressTexView)
}
//33
func SetNavigationItem(){
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "取消", style: .done, target: self, action: #selector(cancelAction))
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "保存", style: .done, target: self, action: #selector(saveAction))
}
//34
func cancelAction() {
self.dismiss(animated: true, completion: nil)
}
//35
func saveAction() {
if nameField.text?.characters.count == 0 || photoField.text?.characters.count == 0{
return print("姓名或电话为空")
}
let acontact = Contact()
acontact.name = nameField.text
acontact.phone = photoField.text
acontact.adress = addressTexView.text
acontact.image = photaView.image
//添加联系人
ContactManager.share.addcontact(acontact: acontact)
self.dismiss(animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//37
func tapAction(sender:UITapGestureRecognizer) {
let alertVC = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let action1 = UIAlertAction(title: "相机", style: .destructive, handler: {(sender:UIAlertAction) in
// print("选择了相机")
self.pickerImageFrontCamera()
})
let action2 = UIAlertAction(title: "相册", style: .destructive, handler: {(sender:UIAlertAction) in
// print("选择了相册")
self.pickerImageFromPhotoLibrary()
})
let action3 = UIAlertAction(title: "取消", style: .cancel, handler: nil)
alertVC.addAction(action1)
alertVC.addAction(action2)
alertVC.addAction(action3)
self.present(alertVC, animated: true, completion: nil)
}
//38
func pickerImageFrontCamera() {
let isCan = UIImagePickerController.isCameraDeviceAvailable(.rear)
let iscan2 = UIImagePickerController.isCameraDeviceAvailable(.front)
if !isCan || !iscan2{
return print("摄像头不可用")
}
//选择图片视图控制器
let pickerVC = UIImagePickerController()
pickerVC.sourceType = .camera
pickerVC.allowsEditing = true
pickerVC.delegate = self
self.present(pickerVC, animated: true, completion: nil)
}
//39
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
self.photaView.image = info[UIImagePickerControllerEditedImage] as! UIImage?
//将模态视图收回
picker.dismiss(animated: true, completion: nil)
}
//40
func pickerImageFromPhotoLibrary(){
let pickerVC = UIImagePickerController()
pickerVC.sourceType = .photoLibrary
pickerVC.allowsEditing = true
pickerVC.delegate = self
self.present(pickerVC, animated: true, completion: nil)
}
ContactManager.swift:
//41
//删除一个分区或者cell的分区属
func deleteRowwOrSection(indexpath:IndexPath) ->Bool{
let key = keys[indexpath.section]
let group = dataSource[key]
if group?.count == 1 {
return true
}
//删除一个
return false
}
//42
//删除分区的方法
func deleteAsection(indexpath:IndexPath){
let key = keys[indexpath.section]
// let group = dataSource[key]
dataSource.removeValue(forKey: key)
keys.remove(at: indexpath.section)
}
//43
//删除cell的方法
func deleteACell(indexpath:IndexPath){
let key = keys[indexpath.section]
var group = dataSource[key]
group?.remove(at: indexpath.row)
dataSource[key] = group
}
//46
func moveContact(fromIndex:IndexPath,toIndex:IndexPath){
let key = keys[fromIndex.section]
var group = dataSource[key]
let acontact = group?[fromIndex.section]
group?.remove(at: fromIndex.row)
group?.insert(acontact!, at: toIndex.row)
dataSource[key] = group
}
ContactListTableViewController.swift“:
/* */
//44
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
/**/
//45
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let result = ContactManager.share.deleteRowwOrSection(indexpath: indexPath)
if result{
ContactManager.share.deleteAsection(indexpath: indexPath)
let set = NSIndexSet(index: indexPath.section)
tableView.deleteSections(set as IndexSet, with: .left)
}else{
ContactManager.share.deleteACell(indexpath: indexPath)
tableView.deleteRows(at: [indexPath], with: .right)
}
}
}
/* */
//47
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
ContactManager.share.moveContact(fromIndex: fromIndexPath, toIndex: to)
}
/**/
//48
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
//49
override func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
if sourceIndexPath.section == proposedDestinationIndexPath.section{
return proposedDestinationIndexPath
}
return sourceIndexPath
}
DetailViewController.swift:(界面传值)
//50
var acontact:Contact?
ContactListTableViewController.swift:
//25
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: systemCell, for: indexPath)
cell.backgroundColor = UIColor.yellow
//26
let acontact = ContactManager.share.contacshowByIndexPath(indexpath: indexPath)
//51
//单例调用返回联系人的方法
cell.imageView?.image = acontact.image
cell.textLabel?.text = acontact.name
cell.detailTextLabel?.text = acontact.phone
return cell
}
DetailViewController.swift:
//52
func setValueForSubView() {
nameLabel.text = acontact?.name
photoView.image = acontact?.image
phoneLabel.text = acontact?.phone
addressLabel.text = acontact?.adress
}