iOS开发-委托实战
昨天晚上头疼,写了一部分草草的收笔了,早上起来补发一篇文章,昨天关于委托的基本使用和概念都稍微讲了一下,最开始学习委托的时候苹果官网和中文的博客文章看了不少,相似指数比较高。委托在命名要准确,最好是一看名字就知道用法,看名字就知道是干什么用的,比如说UINavigationControllerDelegate,UITableViewDelegate,这样命名不管是自己开始还是别人维护都是一个非常省心的事情,一举两得。
页面布局
先来看下效果图,这样大概知道应该实现的内容,效果如下:
这种实现,在故事板中的布局就是一个NavigationController和一个UITableView的静态表格:
其实添加的按钮是控件库中的Bar Buttom Item,将其中的Identifier设置为Add就可以是上面的效果,有一点需要说明的,添加书籍的视图中是静态单元格,需要删除控制器中多余的方法,不然无法出现效果。
Demo实现
上面跟委托有关联的地方就是保存的时候需要将数据讲给主视图去新增,而不是自己新增数据,可以通过定义一个委托实现上面的效果,具体可以参考本人的上一篇文章。需要先定义一个Book类用来存储数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface Book : NSObject < NSCoding > @property (strong, nonatomic ) UIImage *ConverPicture; @property (strong, nonatomic ) NSString *BookName; @property (strong, nonatomic ) NSString *Author; @property (strong, nonatomic ) NSNumber *Price; @end |
Book.m需要存储数据实现两个方法,具体参考之前的文章NSCoder存储数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // // Book.m // MySearchBar // // Created by keso on 15/2/4. // Copyright (c) 2015年 keso. All rights reserved. // #import "Book.h" @implementation Book - ( void )encodeWithCoder:( NSCoder *)aCoder{ //注意这里是存储的是JPG图片的调用 [aCoder encodeObject:UIImageJPEGRepresentation( self .ConverPicture,1.0)forKey:@ "ConverPicture" ]; [aCoder encodeObject:_BookName forKey:@ "BookName" ]; [aCoder encodeObject:_Author forKey:@ "Author" ]; [aCoder encodeObject:_Price forKey:@ "Price" ]; } - ( id )initWithCoder:( NSCoder *)aDecoder{ self .ConverPicture=[UIImage imageWithData:[aDecoder decodeObjectForKey:@ "ConverPicture" ]]; self .BookName=[aDecoder decodeObjectForKey:@ "BookName" ]; self .Author=[aDecoder decodeObjectForKey:@ "Author" ]; self .Price=[aDecoder decodeObjectForKey:@ "Price" ]; return self ; } @end |
首先来看第一个视图:RootViewController.h中的声明:
1 2 3 4 5 6 7 | #import <UIKit/UIKit.h> #import "EditViewController.h" @interface RootViewController : UITableViewController<CustomEditViewControllerDelegate> @end |
RootViewController.m中ViewDiLoad中方法加载数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | - ( void )viewDidLoad { [ super viewDidLoad]; NSArray *codepath= NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES ); self .BookPath= [codepath[0] stringByAppendingPathComponent:@ "Book.plist" ]; //这个路径暂时好像还没有存储数据的说 NSFileManager *fileManager = [ NSFileManager defaultManager]; self .BookList=[[ NSMutableArray alloc]init]; NSLog (@ "%@" , NSHomeDirectory ()); if ([fileManager fileExistsAtPath:_BookPath]){ self .BookList=[ NSKeyedUnarchiver unarchiveObjectWithFile: self .BookPath]; } } |
实现UITableView中的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | - ( NSInteger )numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - ( NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:( NSInteger )section { return [ self .BookList count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath { static NSString *cellflag = @ "BookCellFlag" ; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellflag]; Book *book= self .BookList[indexPath.row]; [cell.textLabel setText:book.BookName]; [cell.detailTextLabel setText:book.Author]; [cell.imageView setImage:book.ConverPicture]; return cell; } - ( void )prepareForSegue:(UIStoryboardSegue *)segue sender:( id )sender{ if ([segue.identifier isEqualToString:@ "editSegue" ]) { EditViewController *controller = segue.destinationViewController; [controller setCustomDelegate: self ]; } } |
prepareForSegue用来处理新增的动作,主视图生命了自定义的委托,需要实现其方法供子视图调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | -( void )saveBookInfo:(EditViewController *)controller{ if ( self .BookList== nil ) { self .BookList=[[ NSMutableArray alloc]init]; } Book *book=controller.OriginalBook; [ self .BookList addObject:book]; //将文件整体写入之后更新数据 [ NSKeyedArchiver archiveRootObject: self .BookList toFile: self .BookPath]; [ self .tableView reloadData]; } |
子视图的.h文件中的声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #import <UIKit/UIKit.h> #import "Book.h" @class EditViewController; #pragma mark - 自定义委托 @protocol CustomEditViewControllerDelegate < NSObject > //定义一个方法,在根视图中保存数据 - ( void )saveBookInfo:(EditViewController *)controller; @end @interface EditViewController : UITableViewController <UIImagePickerControllerDelegate,UIPickerViewDelegate,UIPickerViewDataSource, UINavigationControllerDelegate> @property (weak, nonatomic ) id <CustomEditViewControllerDelegate> customDelegate; @property (strong, nonatomic ) Book *OriginalBook; @property (weak, nonatomic ) IBOutlet UIImageView *converImage; @property (weak, nonatomic ) IBOutlet UITextField *bookNameText; @property (weak, nonatomic ) IBOutlet UITextField *authorText; @property (weak, nonatomic ) IBOutlet UITextField *priceText; @end |
其中需要注意的是自定义的委托,需要传递一个子视图,先用Class声明一下使用到的类,子视图也比较简单,选择图片之前有一篇博客已经写过如何使用,其他的就是控件赋值,详细代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | // // EditViewController.m // MySearchBar // // Created by keso on 15/2/4. // Copyright (c) 2015年 keso. All rights reserved. // #import "EditViewController.h" @interface EditViewController () @end @implementation EditViewController - ( void )viewDidLoad { [ super viewDidLoad]; // Uncomment the following line to preserve selection between presentations. // self.clearsSelectionOnViewWillAppear = NO; // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem; } - ( IBAction )chooseConverImage:( id )sender { UIImagePickerController *picker=[[UIImagePickerController alloc]init]; // 指定照片源 [picker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; // 指定是否允许修改 [picker setAllowsEditing: YES ]; // 指定代理 [picker setDelegate: self ]; // 显示照片选择控制器 [ self .navigationController presentViewController:picker animated: YES completion: nil ]; } - ( void )imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:( NSDictionary *)info{ UIImage *image = info[@ "UIImagePickerControllerEditedImage" ]; //设置图片 [ self .converImage setImage:image]; [ self .navigationController dismissViewControllerAnimated: YES completion: nil ]; } - ( IBAction )saveBook:( id )sender { if ( self .OriginalBook== nil ) { self .OriginalBook=[[Book alloc]init]; } //书籍名称 _OriginalBook.BookName=_bookNameText.text; //封面 _OriginalBook.ConverPicture=_converImage.image; _OriginalBook.Author=_authorText.text; _OriginalBook.Price=[[ NSNumber alloc] initWithFloat:[_priceText.text floatValue]]; // 通知父视图控制器(用户列表)保存用户记录,并且返回 [_customDelegate saveBookInfo: self ]; //返回到上级视图 [ self .navigationController popViewControllerAnimated: YES ]; } - ( void )didReceiveMemoryWarning { [ super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end |
这个也算是一个委托的小Demo吧,比昨天那两个稍微好点,用到的知识点之前的博客中已经写过,如果有问题可以共同探讨,如有不当,可以评论区交流,感激不尽~
出处:http://www.cnblogs.com/xiaofeixiang
说明:博客经个人辛苦努力所得,如有转载会特别申明,博客不求技惊四座,但求与有缘人分享个人学习知识,生活学习提高之用,博客所有权归本人和博客园所有,如有转载请在显著位置给出博文链接和作者姓名,否则本人将付诸法律。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述