通讯录 CoreData & tabelView

数据持久化的增删改查

通过 FRC 和 CoreData 动态刷新tabelView 数据


#import "ViewController.h"

#import "Person.h"


@interface ViewController ()<UISearchResultsUpdating,UISearchControllerDelegate,NSFetchedResultsControllerDelegate,UITableViewDataSource,UITableViewDelegate>


@property (weak, nonatomic) IBOutlet UIView *seachView;


@property(nonatomic,strong)UISearchController * searchController;


@property (weak, nonatomic) IBOutlet UITableView *tableView;


@property(nonatomic,strong)NSManagedObjectContext * managedObjectContext;

@property(nonatomic,strong)NSFetchedResultsController * fetchedResultsController;




@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    [self loadShuJu];

    [self loadSearch];

    

    

}


-(void)viewDidAppear:(BOOL)animated{

    [self updateSearchResultsForSearchController:self.searchController];

}


//配置 searchController

-(void)loadSearch

{

    self.searchController = [[UISearchController alloc]initWithSearchResultsController:nil];

//    使 searchBar的大小自动适应 searchController 的大小

    [self.searchController.searchBar sizeToFit];

//    是否可以在子代视图中显示

    self.definesPresentationContext = YES;

//    编辑搜索框时是否隐藏背景

    self.searchController.dimsBackgroundDuringPresentation = NO;

//    编辑搜索框时是否隐藏 navigationBar

    self.searchController.hidesNavigationBarDuringPresentation = NO;

//    贴视图

    [self.seachView addSubview:self.searchController.searchBar];

//    设置代理

    self.searchController.searchResultsUpdater = self;

    self.searchController.delegate = self;

}


//配置数据

-(void)loadShuJu

{

//    设置代理

    self.tableView.dataSource = self;

    

//    获取上下文

    UIApplication * app = [UIApplication sharedApplication];

    id delegate = app.delegate;

    self.managedObjectContext = [delegate managedObjectContext];

    

//    通过实体名获取请求

    NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Person class])];

//    排序规则

    NSSortDescriptor * sort1 = [NSSortDescriptor sortDescriptorWithKey:@"firstN" ascending:YES];

    NSSortDescriptor * sort2 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];

    

    [request setSortDescriptors:@[sort1,sort2]];

    

//    请求转化为需要显示的数据

    self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"firstN" cacheName:nil];

    

    NSError * error;

//    执行 fetchedResultsController

    if (![self.fetchedResultsController performFetch:&error]) {

        NSLog(@"%@",error.localizedDescription);

        return;

    }

    

//    代理

    self.fetchedResultsController.delegate = self;

}



#pragma mark - 配置 tabelView


//section

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{

    return self.fetchedResultsController.sections.count;

}


//每个 section 的行数

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    NSArray * sections = self.fetchedResultsController.sections;

    id<NSFetchedResultsSectionInfo>sectionInfo = sections[section];

    return [sectionInfo numberOfObjects];

}


//每个 cell 显示的内容

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    Person * person = [self.fetchedResultsController objectAtIndexPath:indexPath];

    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

    cell.textLabel.text = person.name;

    cell.detailTextLabel.text = person.tel;

    cell.imageView.image = person.headImg;

    

    return cell;

}


//每个 section 的标题

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

{

    NSArray * arr = [self.fetchedResultsController sections];

    id<NSFetchedResultsSectionInfo>secInfo = arr[section];

    return [secInfo name];

}



//一下三个回调配置删除,增加数据(以删除为例)


// 是否可编辑

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

{

    return YES;

}



-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

{

    return UITableViewCellEditingStyleDelete;

}


//点击删除按钮时执行的操作

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

{

    Person * person = [self.fetchedResultsController objectAtIndexPath:indexPath];

    [self.managedObjectContext deleteObject:person];

    NSError * error;

    if (![self.managedObjectContext save:&error]) {

        NSLog(@"%@",error.localizedDescription);

        return;

    }

}



#pragma mark - 配置 searchController 回调


//当搜索框文本变化是执行的操作

-(void)updateSearchResultsForSearchController:(UISearchController *)searchController

{


//    优化代码

    if (![[searchController.searchBar text] length]) {

        [self loadShuJu];

        [self.tableView reloadData];

        return;

    }

    


    NSFetchRequest * requset = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Person class])];

    

//    谓词查询   CONTAINS[cd] 表示包含

//                OR  表示

    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@ OR tel CONTAINS[cd] %@",[self.searchController.searchBar text],[self.searchController.searchBar text]];

   

    

    [requset setPredicate:predicate];

    

    NSSortDescriptor * sort1 = [NSSortDescriptor sortDescriptorWithKey:@"firstN" ascending:YES];

    NSSortDescriptor * sort2 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];

    

    [requset setSortDescriptors:@[sort1,sort2]];

    

    self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:requset managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"firstN" cacheName:nil];

    NSError * error;

    if (![self.fetchedResultsController performFetch:&error]) {

        NSLog(@"%@",error.localizedDescription);

        return;

    }

//    此时 fetchedResultsController 已经变化,但是 tabelView 还没有变化,需要 reloadData 一下

    [self.tableView reloadData];

}


//当点击取消搜索时的回调

-(void)didDismissSearchController:(UISearchController *)searchController

{

    [self loadShuJu];

    [self.tableView reloadData];

}





//点击 cell 进入到编辑页面需要传值

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

    if ([sender isKindOfClass:[UITableViewCell class]]) {

        NSLog(@"传值");

        UITableViewCell * cell = (UITableViewCell *)sender;

        NSIndexPath * indexpath = [self.tableView indexPathForCell:cell];

        Person * person =   [self.fetchedResultsController objectAtIndexPath:indexpath];

        UIViewController * view = [segue destinationViewController];

//        下一个 View 应该设置一个属性名为 person key 的值)的属性用来接收 person

        [view setValue:person forKey:@"person"];

    }

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}




// FRC 回调


- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {

    [self.tableView beginUpdates];

}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo

           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    

    switch(type) {

        case NSFetchedResultsChangeInsert:

            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]

                          withRowAnimation:UITableViewRowAnimationFade];

            break;

            

        case NSFetchedResultsChangeDelete:

            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]

                          withRowAnimation:UITableViewRowAnimationFade];

            break;

    }

}



- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject

       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type

      newIndexPath:(NSIndexPath *)newIndexPath {

    

    UITableView *tableView = self.tableView;

    

    switch(type) {

            

        case NSFetchedResultsChangeInsert:

            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]

                             withRowAnimation:UITableViewRowAnimationFade];

            break;

            

        case NSFetchedResultsChangeDelete:

            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]

                             withRowAnimation:UITableViewRowAnimationFade];

            break;

            

        case NSFetchedResultsChangeUpdate:

            [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

            break;

            

        case NSFetchedResultsChangeMove:

            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]

                             withRowAnimation:UITableViewRowAnimationFade];

            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]

                             withRowAnimation:UITableViewRowAnimationFade];

            break;

    }

}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {

    [self.tableView endUpdates];

}

@end



#import "AddTableViewController.h"

#import "Person.h"


@interface AddTableViewController ()<UIImagePickerControllerDelegate,UIActionSheetDelegate>


@property (weak, nonatomic) IBOutlet UIButton *headImg;


@property (weak, nonatomic) IBOutlet UITextField *lblName;


@property (weak, nonatomic) IBOutlet UITextField *lblTel;


@property(nonatomic,strong)NSManagedObjectContext * managedObjectContext;


@property(nonatomic,strong)Person * person;


@property(nonatomic,strong)UIImagePickerController * picker;


@end


@implementation AddTableViewController





- (void)viewDidLoad {

    [super viewDidLoad];

    

    [self loadShuJu];

    

}



-(void)loadShuJu

{

    UIApplication * app = [UIApplication sharedApplication];

    id delegate = app.delegate;

    self.managedObjectContext = [delegate managedObjectContext];

    

//    编辑,添加用的是同一页面,所以需要进行判断

    if (self.person) {

        self.lblName.text = self.person.name;

        self.lblTel.text = self.person.tel;

        [self.headImg setImage:self.person.headImg forState:UIControlStateNormal];

        [self.managedObjectContext deleteObject:self.person];

        NSError * error;

        if (![self.managedObjectContext save:&error]) {

            NSLog(@"%@",error.localizedDescription);

            return;

        }

        NSLog(@"编辑");

        

        self.title = @"编辑";

    }else{

        self.title = @"添加联系人";

        NSLog(@"联系");

    }

}


//界面显示时初始化 UIImagePickerController

-(void)viewDidAppear:(BOOL)animated{

    self.picker = [[UIImagePickerController alloc]init];

}


- (IBAction)tapHeadImg:(id)sender {

//    UIImagePickerController 代理

    self.picker.delegate = self;

    

    UIActionSheet* actionSheet = [[UIActionSheet alloc]

                                  initWithTitle:@"请选择文件来源"

                                  delegate:self

                                  cancelButtonTitle:@"取消"

                                  destructiveButtonTitle:nil

                                  otherButtonTitles:@"照相机",@"摄像机",@"本地相簿",@"本地视频",nil];

    [actionSheet showInView:self.view];

    

    

}


//通过 actionSheet 选择UIImagePickerController type

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

{

    switch (buttonIndex) {

        case 0://照相机

        {

            self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;

            [self presentViewController:self.picker animated:YES completion:nil];

        }

            break;

        case 1://摄像机

        {

            

            self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;

            self.picker.videoQuality = UIImagePickerControllerQualityTypeLow;

            [self presentViewController:self.picker animated:YES completion:nil];

        }

            break;

        case 2://本地相簿

        {

            

            self.picker.allowsEditing = YES;

            self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

            [self presentViewController:self.picker animated:YES completion:nil];

        }

            break;

        case 3://本地视频

        {

            

            self.picker.allowsEditing = YES;

            self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

            [self presentViewController:self.picker animated:YES completion:nil];

        }

            break;

        default:

            break;

    }

}


// UIImagePickerController 选择完图片时的回调

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{

    UIImage * image = info[UIImagePickerControllerOriginalImage];

    [self.headImg setImage:image forState:UIControlStateNormal];

    [self dismissViewControllerAnimated:YES completion:nil];

}



- (IBAction)save:(id)sender {

     self.person = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Person class]) inManagedObjectContext:self.managedObjectContext];

    self.person.name = self.lblName.text;

    self.person.tel = self.lblTel.text;

    self.person.headImg = self.headImg.currentImage;

    self.person.firstN = self.person.getFirstN;

    

    NSError * error;

    if (![self.managedObjectContext save:&error]) {

        NSLog(@"%@",error.localizedDescription);

        return;

    }


//    如果 name Tel 都为空,则删除这条数据(当时想过如果在上一条就进行判断,如果为空则直接不进行保存即可,但是这样在返回到电话簿首页时会显示一条空数据,这条数据没有保存,在下次重启程序时不会显示,这个问题在使用 UITabelViewController 时是不存在的,

    

    if ((![self.person.name length]) && (![self.person.tel length])) {


        [self.managedObjectContext deleteObject:self.person];

        NSError * error;

        if (![self.managedObjectContext save:&error]) {

            NSLog(@"%@",error.localizedDescription);

            return;

        }


    }


//    返回上一界面

    [self.navigationController popViewControllerAnimated:YES];

    

}



- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end






1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值