ios开发基础之通讯录系统实战

基础知识 OC 基础
segue 的使用。delegate 代理的使用 自定义代理。面向对象思想 沙盒容器的数据持久化方案,
controller 之间的跳转 ,登录方法。UITableViewController的使用 导航条的使用等知识点的使用
我们使用最新的Xcode12。4 版本,配合最新的ios14.3系统和最新的mac os x系统,跑在 vmware 15虚拟机上面,需要电脑配置较高,否则比较卡顿;

实现的主要功能的截图。有些api虽然已经过期了,但是不影响使用。 ,先把过期的学好,再学新出的api函数





//
//  LoginViewController.m
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/13.
//#import "LoginViewController.h"
#import "MBProgressHUD+NJ.h"
#import "SVProgressHUD.h"
#import "ContactViewController.h"@interface LoginViewController () <UITextFieldDelegate>@property (weak, nonatomic) IBOutlet UITextField *usernameView;@property (weak, nonatomic) IBOutlet UITextField *pwdView;@property (weak, nonatomic) IBOutlet UIButton *loginBtn;
- (IBAction)loginClick:(id)sender;@property (weak, nonatomic) IBOutlet UISwitch *remPwd;
@property (weak, nonatomic) IBOutlet UISwitch *autoLoginSw;@end@implementation LoginViewController- (IBAction)remClick:(UISwitch *)sender {if(!sender.isOn){//        self.autoLoginSw.on=NO;[self.autoLoginSw setOn:NO animated:YES];}}- (IBAction)autoLoginClick:(UISwitch *)sender {if(sender.isOn){//        self.remPwd.on = YES;[self.remPwd setOn:YES animated:YES];}}//页面之间的传值
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ContactViewController *contactVc  = segue.destinationViewController;[contactVc setUsername:self.usernameView.text];
}- (IBAction)loginClick:(id)sender {// [SVProgressHUD showWithStatus:@"正在登录" maskType:SVProgressHUDMaskTypeBlack];[MBProgressHUD showMessage:@"正在登录"];//模拟网络延时dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(3 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{//  [SVProgressHUD dismiss];[MBProgressHUD hideHUD];if([self.usernameView.text isEqualToString:@"1"] &&[self.pwdView.text isEqualToString:@"1"]){[self performSegueWithIdentifier:@"login2contact" sender:nil];NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];[userDefaults setBool:self.remPwd.isOn forKey:@"remPwdKey"];[userDefaults setBool:self.autoLoginSw.isOn forKey:@"autoLoginKey"];[userDefaults setObject:self.usernameView.text forKey:@"usernameViewKey"];[userDefaults setObject:self.pwdView.text forKey:@"pwdViewKey"];[userDefaults synchronize];}else{//[SVProgressHUD showErrorWithStatus:@"用户名或者密码错误"];[MBProgressHUD showError:@"用户名或者密码错误"];}});}
- (void)viewDidLoad {[super viewDidLoad];[self.usernameView addTarget:self action:@selector(changeValue) forControlEvents:(UIControlEventEditingChanged)];[self.pwdView addTarget:self action:@selector(changeValue) forControlEvents:(UIControlEventEditingChanged)];self.usernameView.delegate =self;//恢复状态NSUserDefaults *ud=[NSUserDefaults standardUserDefaults];self.remPwd.on = [ud boolForKey:@"remPwdKey"];self.autoLoginSw.on = [ud boolForKey:@"autoLoginKey"];self.usernameView.text  = [ud objectForKey:@"usernameViewKey"];if(self.remPwd.isOn){self.pwdView.text  = [ud objectForKey:@"pwdViewKey"];}if(self.autoLoginSw.isOn){[self loginClick:nil];}[self changeValue];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{[self.view endEditing:YES];}//这是文本框的代理方法
-(void)text1
{//    - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;        // return NO to disallow editing.
//    - (void)textFieldDidBeginEditing:(UITextField *)textField;           // became first responder
//    - (BOOL)textFieldShouldEndEditing:(UITextField *)textField;          // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
//    - (void)textFieldDidEndEditing:(UITextField *)textField;             // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
//    - (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason API_AVAILABLE(ios(10.0)); // if implemented, called in place of textFieldDidEndEditing:
//
//    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;   // return NO to not change text
//
//    - (void)textFieldDidChangeSelection:(UITextField *)textField API_AVAILABLE(ios(13.0), tvos(13.0));
//
//    - (BOOL)textFieldShouldClear:(UITextField *)textField;               // called when clear button pressed. return NO to ignore (no notifications)
//    - (BOOL)textFieldShouldReturn:(UITextField *)textField;              // called when 'return' key pressed. return NO to ignore.
//
}
-(void)changeValue{self.loginBtn.enabled=self.usernameView.text.length>0 && self.pwdView.text.length>0;
//    if(self.usernameView.text.length>0 && self.pwdView.text.length>0){//        self.loginBtn.enabled = YES;
//
//    }else{//
//        self.loginBtn.enabled = NO;
//
//    }
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {// Get the new view controller using [segue destinationViewController].// Pass the selected object to the new view controller.
}
*/
@end
//
//  ContactViewController.h
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/13.
//#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface ContactViewController : UITableViewController
@property(nonatomic,copy)NSString *username;@endNS_ASSUME_NONNULL_END
//
//  ContactViewController.m
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/13.
//#import "ContactViewController.h"
#import "AddViewController.h"
#import "EditViewController.h"#define kFilePath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"contact.data"]@interface ContactViewController () <UIActionSheetDelegate,AddViewControllerDelegate,UITableViewDataSource,UITableViewDelegate,EditViewControllerDelegate>@property(nonatomic,strong)NSMutableArray *contacts;@end@implementation ContactViewController//rang tableView jin ru bian ji mo shi  hua dong sha chu
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{NSLog(@"213");//[self.contacts removeObject:self.contacts[indexPath.row]];[self.contacts removeObjectAtIndex:indexPath.row];// [self.tableView reloadData];// dong hua xiao guo[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];[NSKeyedArchiver archiveRootObject:self.contacts toFile:kFilePath];}//cell长啥样
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{static NSString *cellID = @"contact_cell";UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:cellID];cell.textLabel.text = [self.contacts[indexPath.row] name];NSLog(@"dajun = %@",[self.contacts[indexPath.row] name]);cell.detailTextLabel.text=[self.contacts[indexPath.row] number];return  cell;}//某一组有多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{return  self.contacts.count;}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{NSLog(@"%ld",self.contacts.count);return  1;}- (NSMutableArray *)contacts{if(!_contacts){_contacts = [NSMutableArray array];}return _contacts;
}//- (void)addViewController:(AddViewController *)addViewController withName:(NSString *)name andPhoneNumber:(NSString *)phoneNumber{//    NSLog(@"name = %@=====phoneNumber = %@",name,phoneNumber);
//}// 添加联系人的代理方法(逆传)- (void)addViewController:(AddViewController *)addViewController withContact:(Contact *)contact{NSLog(@"name = %@=====phoneNumber = %@",contact.name,contact.number);[self.contacts addObject:contact];[self.tableView reloadData];//保存联系人信息//    NSString *docPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
//    NSString *filePath = [docPath stringByAppendingPathComponent:@"contact.data"];//    NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"contact.data"];
//[NSKeyedArchiver archiveRootObject:self.contacts toFile:kFilePath];NSLog(@"%@",NSHomeDirectory());}- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{//  AddViewController *addVc = segue.destinationViewController;
//    addVc.delegate = self;
//UIViewController *vc=segue.destinationViewController;if([vc isKindOfClass:[AddViewController class]]){//设置代理AddViewController *add=(AddViewController *)vc;add.delegate=self;}else{//什么也不做EditViewController *edit =(EditViewController *)vc;edit.delegate = self;//获取点击的Cell的位置。indexPathNSIndexPath *path = [self.tableView indexPathForSelectedRow];Contact *con=self.contacts[path.row];edit.contact = con;}}//第二种方法。不用代理的方法
//- (void)viewWillAppear:(BOOL)animated{//    [super viewWillAppear:animated];
//    [self.tableView reloadData];
//
//
//}
//- (void)viewDidAppear:(BOOL)animated{//
//    [super viewDidAppear:animated];
//    [self.tableView reloadData];
//}-(void)editViewController:(EditViewController *)editViewController withContact:(Contact *)contact{//  NSLog(@"%@,-----%@",contact.name,contact.number);[self.tableView reloadData];// gui dang shu zu (lian xi ren xin xi)[NSKeyedArchiver archiveRootObject:self.contacts toFile:kFilePath];
}-(void)logOut{//    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"你确定要注销吗?" delegate:self cancelButtonTitle:@"qu取消" destructiveButtonTitle:@"注销" otherButtonTitles:nil];
//    [sheet showInView:self.view];NSLog(@"1231243");UIAlertController *actionSheetController = [UIAlertController alertControllerWithTitle:@"你确定要注销吗?" message:nil preferredStyle:UIAlertControllerStyleActionSheet];[actionSheetController addAction:[UIAlertAction actionWithTitle:@"注销" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {[self.navigationController popViewControllerAnimated:YES];}]];[actionSheetController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {}]];[self presentViewController:actionSheetController animated:YES completion:nil];
}//- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{//
//    NSLog(@"%ld",buttonIndex);
//
//    if(buttonIndex==0){//        [self.navigationController popViewControllerAnimated:YES];
//
//    }
//
//
//}- (void)viewDidLoad {[super viewDidLoad];UIBarButtonItem *item0=[[UIBarButtonItem alloc] initWithTitle:@"注销" style:UIBarButtonItemStylePlain target:self action:@selector(logOut)];//细字体self.navigationItem.leftBarButtonItem=item0;NSString *strTitle = [NSString stringWithFormat:@"%@的联系人列表",self.username];self.navigationItem.title = strTitle;self.contacts = [NSKeyedUnarchiver unarchiveObjectWithFile:kFilePath];}-(void)test1{UIBarButtonItem *item0=[[UIBarButtonItem alloc] initWithTitle:@"注销" style:UIBarButtonItemStylePlain target:self action:nil];//细字体UIBarButtonItem *item1=[[UIBarButtonItem alloc] initWithTitle:@"注销" style:UIBarButtonItemStyleDone target:self action:nil];// 粗字体self.navigationItem.leftBarButtonItems=@[item0,item1];
}@end
//
//  AddViewController.h
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/13.
//#import <UIKit/UIKit.h>
#import "Contact.h"
@class AddViewController;// 添加协议。 进行传值
NS_ASSUME_NONNULL_BEGIN@protocol AddViewControllerDelegate <NSObject>@optional
//-(void)addViewController:(AddViewController *)addViewController withName:(NSString *)name andPhoneNumber:(NSString *)phoneNumber;-(void)addViewController:(AddViewController *)addViewController withContact:(Contact *)contact;@end@interface AddViewController : UIViewController@property(nonatomic,weak)id<AddViewControllerDelegate> delegate;@endNS_ASSUME_NONNULL_END
//
//  AddViewController.m
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/13.
//#import "AddViewController.h"
#import "Contact.h"@interface  AddViewController()@property (weak, nonatomic) IBOutlet UITextField *phoneView;@property (weak, nonatomic) IBOutlet UITextField *addNameView;
- (IBAction)addClick:(id)sender;
@property (weak, nonatomic) IBOutlet UIButton *addBtn;@end@implementation AddViewController- (void)viewDidLoad{[self.addNameView addTarget:self action:@selector(changeValue) forControlEvents:UIControlEventEditingChanged];[self.phoneView addTarget:self action:@selector(changeValue) forControlEvents:UIControlEventEditingChanged];self.addBtn.enabled=NO;// 让姓名文本框成为第一响应者[self.addNameView becomeFirstResponder]; //自动弹出键盘}-(void)changeValue{self.addBtn.enabled=self.addNameView.text.length>0&&self.phoneView.text.length;
}- (IBAction)addClick:(id)sender {//使用自定义的代理方法//判断代理方法是不是能够响应
//    if([self.delegate respondsToSelector:@selector(addViewController:withName:andPhoneNumber:)]){//
//        [self.delegate addViewController:self withName:self.addNameView.text andPhoneNumber:self.phoneView.text];
//
//        传统的做法
//
//    }if([self.delegate respondsToSelector:@selector(addViewController:withContact:)]){Contact *contact = [[Contact alloc] init];contact.name = self.addNameView.text;contact.number = self.phoneView.text;[self.delegate addViewController:self withContact:contact];}[self.navigationController popViewControllerAnimated:YES];}
@end
//
//  Contact.h
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/14.
//#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Contact : NSObject <NSCoding>@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *number;@endNS_ASSUME_NONNULL_END
//
//  Contact.m
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/14.
//#import "Contact.h"@implementation Contact//dui dang
- (void)encodeWithCoder:(NSCoder *)coder
{[coder encodeObject:_name forKey:@"name"];[coder encodeObject:_number forKey:@"number"];}- (instancetype)initWithCoder:(NSCoder *)coder
{self = [super init];if (self) {_name = [coder decodeObjectForKey:@"name"];_number = [coder decodeObjectForKey:@"number"];}return self;
}@end
//
//  EditViewController.h
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/14.
//#import <UIKit/UIKit.h>
#import "Contact.h"
NS_ASSUME_NONNULL_BEGIN
@class EditViewController;@protocol EditViewControllerDelegate <NSObject>@optional
-(void)editViewController:(EditViewController *)editViewController withContact:(Contact *)contact;@end@interface EditViewController : UIViewController
@property(nonatomic,strong)Contact *contact;@property(nonatomic,weak)id<EditViewControllerDelegate> delegate;@endNS_ASSUME_NONNULL_END
//
//  EditViewController.m
//  20-通讯录
//
//  Created by 鲁军 on 2021/2/14.
//#import "EditViewController.h"@interface EditViewController ()
- (IBAction)editClick:(id)sender;
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *numberField;
@property (weak, nonatomic) IBOutlet UIButton *saveBtn;
- (IBAction)saveBtnClick:(id)sender;@end@implementation EditViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.nameField.text = self.contact.name;self.numberField.text = self.contact.number;}/*
#pragma mark - Navigation// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {// Get the new view controller using [segue destinationViewController].// Pass the selected object to the new view controller.
}
*/- (IBAction)editClick:(UIBarButtonItem *)sender {//if([sender.title isEqualToString:@"编辑"]){if(self.saveBtn.hidden){ // dian ji bian jisender.title=@"取消";self.nameField.enabled=YES;self.numberField.enabled=YES;self.saveBtn.hidden=NO;//让电话的文本框成为第一响应者 弹出虚拟 键盘[self.numberField becomeFirstResponder];}else{  // dian ji  qu  xiao sender.title=@"编辑";self.nameField.enabled=NO;self.numberField.enabled=NO;self.saveBtn.hidden=YES;//chong xin fu  zhiself.nameField.text = self.contact.name;self.numberField.text = self.contact.number;}}
- (IBAction)saveBtnClick:(id)sender {if(self.nameField.text.length==0 &&self.numberField.text.length==0){return;}self.contact.name=self.nameField.text;self.contact.number =self.numberField.text;
//    Contact *con =[[Contact alloc] init];
//    con.name=self.nameField.text;
//    con.number=self.numberField.text;//判断代理方法是不是可以响应代理方法if([self.delegate respondsToSelector:@selector(editViewController:withContact:)]){[self.delegate editViewController:self withContact:nil];}[self.navigationController popViewControllerAnimated:YES];}
@end

ios开发基础之通讯录系统实战-20相关推荐

  1. Python自动化开发基础 分布式监控系统开发实战 day8-李杰-专题视频课程

    Python自动化开发基础 分布式监控系统开发实战 day8-10994人已学习 课程介绍         从0基础开始讲解Python语法.流程控制.函数式编程.面向对象开发等重要的Python开发 ...

  2. iOS开发基础知识--碎片44

    iOS开发基础知识--碎片44  iOS开发基础知识--碎片44 1:App跳转至系统Settings 跳转在IOS8以上跟以下是有区别的,如果是IOS8以上可以如下设置: NSURL *url = ...

  3. IOS开发基础之OC的Block入门_Day09-Block

    IOS开发基础之OC的Block入门_Day09-Block block是oc的重要的基础知识,重点之重.跟协议一样重要,是进行函数回调重要手段.在后续的UI学习具有举足轻重的地位.学会基础的bloc ...

  4. iOS开发基础知识--碎片19

    iOS开发基础知识--碎片19  1:键盘事件顺序 UIKeyboardWillShowNotification // 键盘显示之前 UIKeyboardDidShowNotification // ...

  5. iOS开发基础-九宫格坐标(4)

    对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...

  6. IOS开发基础之微博项目第1天-OC版

    IOS开发基础之微博项目第1天-OC版 纯代码创建的项目,具有参考价值 该资料来自2014年7月3号,虽然时间过去较长,但是oc和swift不同,oc语法迭代更新慢 具有一定的参考意义 涉及xib加载 ...

  7. IOS开发基础之SQLite3数据库的使用增删改查

    IOS开发基础之SQLite3数据库的使用增删改查 ios开发我们可能会使用到数据库进行持久化存储.sqlite3 是轻量级的数据库. 今天我们来介绍sqlite3 数据库.此方法跟java的增删改查 ...

  8. IOS开发基础之绘制饼图、柱状图、自定义进度条

    IOS开发基础之绘制饼图.柱状图.自定义进度条 源码在我的主页里 1.绘制饼图 效果 源码 // LJView.m // 34-绘图饼图 // Created by 鲁军 on 2021/2/23. ...

  9. IOS开发基础之截图、图片文字水印

    IOS开发基础之截图.图片文字水印 项目源码在我的主页里面. // // ViewController.m // 31-屏幕截图 // // Created by 鲁军 on 2021/2/22. / ...

最新文章

  1. 带宽与流量的基本概念(更新)
  2. MySQL 8.0 压缩包版安装方法
  3. microsoft符合服务器加载符号的解决方案
  4. 分类二级联动 php,学习猿地-php实现二级联动菜单
  5. .net web 点击链接在页面指定位置显示DIV的问题
  6. stupid soso spider
  7. __cplusplus、extern “C”关键字意义
  8. AD属性对照表 LDAP
  9. 线段树、前缀数组:HDU1591-Color the ball(区间更新、简单题)
  10. Linux系统下卸载VMware Workstation软件
  11. STRUTS1框架简介
  12. IDEA 不检查语法错误问题
  13. 2021年起重机司机(限桥式起重机)考试题库及起重机司机(限桥式起重机)考试试卷
  14. python打开文件对话框
  15. Lively Wallpaper 免费开源动画桌面壁纸,让您的桌面栩栩如生!
  16. 一些有趣的软件分享,给生活带来一点乐趣
  17. 盘点国有银行发行数字人民币现状:正全面加速落地
  18. 【技术美术图形部分】图形渲染管线2.0-GPU管线概述几何阶段
  19. 暴力英语学习法 + 严格的目标管理 = 成功快速靠谱的学好英语
  20. SYN6288移植51程序

热门文章

  1. java地图点线面_openlayers之点,线,面(以城市,河流,省份为例,分别对应点线面)...
  2. java找出一组数据缺少最小数组_Java获取一维数组的最小值实现方法
  3. FIR_01 基于FPGA的FIR滤波器 (FDATOOL ISE ) 第一篇:初步认识和应用
  4. 有没有python的班_【万字长文】别再报班了,一篇文章带你入门Python
  5. python的opencv库_用于Python的Opencv可视化库安装,面向,OpenCV,视觉
  6. shell python脚本语言_python脚本里使用shell语句
  7. 究竟什么是Linux内核?我该如何高效学习?​
  8. windows下的库文件在linux的使用,Windows、Linux之间传输文件的几种方式
  9. mysql 设计两个主键都不可重复_18个MySQL面试题剖析(答案解析),听说身为程序员的你还没掌握...
  10. sizeof 数组_简单的一维数组竟然有这么多坑?