NSFetchedResultController与UITableView

 1 #import "AppDelegate.h"
 2 #import "Book.h"
 3 @interface AppDelegate ()
 4 @end
 5 @implementation AppDelegate
 6 -(void)addBookWithTitle:(NSString *)title andAuthor:(NSString *)author andPrice:(NSNumber *)price
 7 {
 8     Book *book = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Book class]) inManagedObjectContext:self.managedObjectContext];
 9     book.title = title;
10     book.author = author;
11     book.price = price;
12 }
13 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
14     //如果不想每次执行时测试数据都重新插入一遍,可以使用偏好设置,如果已经存在了,就不再进行插入了。
15     NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
16     BOOL isInserted = [userDefaults boolForKey:@"inInserted"];
17     if (!isInserted)
18     {
19         //插入数据
20         [self addBookWithTitle:@"*文*" andAuthor:@"徐" andPrice:@10000.1];
21         [self addBookWithTitle:@"西游记" andAuthor:@"吴承恩" andPrice:@20.5];
22         [self addBookWithTitle:@"水浒传" andAuthor:@"施耐庵" andPrice:@5.1];
23         [self addBookWithTitle:@"三国演义" andAuthor:@"罗贯中" andPrice:@10.2];
24         [self addBookWithTitle:@"史记" andAuthor:@"司马迁" andPrice:@45.3];
25         [self addBookWithTitle:@"资治通鉴" andAuthor:@"司马光" andPrice:@56.5];
26         [self saveContext];
27         //保存偏好设置
28         [userDefaults setBool:YES forKey:@"inInserted"];
29         //自动步更新
30         [userDefaults synchronize];
31     }
32     return YES;
33 }
  1 #import "BookTableViewController.h"
  2 #import "Book.h"
  3 #import "AppDelegate.h"
  4 @interface BookTableViewController ()<NSFetchedResultsControllerDelegate>
  5 @property(strong,nonatomic)NSFetchedResultsController *fetchedRC;
  6 @property(strong,nonatomic)NSManagedObjectContext *managedObjectContext;
  7 @end
  8
  9 @implementation BookTableViewController
 10
 11 - (void)viewDidLoad {
 12     [super viewDidLoad];
 13     //获取应用代理
 14     AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
 15     //本次案例需要对CoreData的内容进行修改,涉及到managedObjectContext,但是magagedObjetContext属于Appdelegate的属性,此处使用协议获取创建新的managedObjectContext;
 16     self.managedObjectContext = delegate.managedObjectContext;
 17     //使用fetchedRC获取数据
 18     NSError *error = nil;
 19     [self.fetchedRC performFetch:&error];
 20     if (error) {
 21         NSLog(@"NSFetchedResultsController获取数据失败");
 22     }
 23 }
 24 -(NSFetchedResultsController *)fetchedRC
 25 {
 26     //判断fetchRC是否存在,如果不存在则创建新的,否则直接返回
 27     if (!_fetchedRC) {
 28         //使用NSFetchRequest进行获取数据
 29         NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Book class])];
 30         request.fetchBatchSize = 20;
 31         //设置以某个字段进行排序,此案例以:price价格大小进行排序
 32         NSSortDescriptor *priceSort = [NSSortDescriptor sortDescriptorWithKey:@"price" ascending:YES];
 33         //对获取的数据进行排序
 34         [request setSortDescriptors:@[priceSort]];
 35         //创建新的fetchedRC
 36         _fetchedRC = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
 37         _fetchedRC.delegate = self;
 38     }
 39     return _fetchedRC;
 40 }
 41
 42 #pragma mark - Table view data source
 43 //设置tableView的分组数
 44 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
 45 {
 46     //分组的数据取决于创建sectionNameKeyPath的设置;
 47     return self.fetchedRC.sections.count;
 48 }
 49 //设置tableView每组有多少行
 50 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 51     id sectionsInfo = [self.fetchedRC.sections objectAtIndex:section];
 52     return [sectionsInfo numberOfObjects];
 53 }
 54 //自定义方法,设置单元格的显示内容
 55 -(void)configCell:(UITableViewCell *)cell andIndexPath:(NSIndexPath *)indexPath
 56 {
 57     //获取选中的对象
 58     Book *book = [self.fetchedRC objectAtIndexPath:indexPath];
 59     cell.textLabel.text = [NSString stringWithFormat:@"%@ %@",book.title,book.author];
 60     cell.detailTextLabel.text = [NSString stringWithFormat:@"%@",book.price];
 61 }
 62 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 63 {
 64     //1.根据reuseindentifier先到对象池中去找重用的单元格
 65     static NSString *reuseIndetifier = @"bookCell";
 66     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndetifier];
 67     //2.如果没有找到需要自己创建单元格对象
 68     if (cell == nil) {
 69         cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIndetifier];
 70     }
 71     //3.设置单元格对象的内容
 72     [self configCell:cell andIndexPath:indexPath];
 73     return cell;
 74 }
 75 // Override to support conditional editing of the table view.
 76 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
 77     // Return NO if you do not want the specified item to be editable.
 78     return YES;
 79 }
 80 // Override to support editing the table view.
 81 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 82     if (editingStyle == UITableViewCellEditingStyleDelete)
 83     {
 84         Book *book = [self.fetchedRC objectAtIndexPath:indexPath];
 85         //1.先删除CoreData中的相应数据
 86         [self.managedObjectContext deleteObject:book];
 87         //插入新的记录
 88         AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
 89         [delegate addBookWithTitle:@"唐诗三百首" andAuthor:@"李白等" andPrice:@12.3];
 90         book.price = @([book.price doubleValue]+10);
 91         NSError *error = nil;
 92         [self.managedObjectContext save:&error];
 93         if(error) {
 94             NSLog(@"失败");
 95         }
 96     } else if (editingStyle == UITableViewCellEditingStyleInsert)
 97     {
 98     }
 99 }
100 #pragma mark - NSFetchedResultsController代理方法
101 -(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
102 {
103     [self.tableView beginUpdates];
104 }
105 -(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
106 {
107     [self.tableView endUpdates];
108 }
109 /**
110  * 以下方法共进行了两项操作:
111     1.判断操作的类型
112     2.对修改的数据、或新插入的数据位置进行局部刷新
113  */
114 -(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
115 {
116     if (type == NSFetchedResultsChangeDelete)//删除操作
117     {
118         [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
119     }
120     else if (type == NSFetchedResultsChangeInsert)//插入操作
121     {
122         [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
123     }
124     else if (type == NSFetchedResultsChangeUpdate)//更新操作
125     {
126         //首先获取cell;
127         UITableViewCell *cell = [self.fetchedRC objectAtIndexPath:indexPath];
128         //调用configCell方法
129         [self configCell:cell andIndexPath:indexPath];
130         //重新加载指定行
131         [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
132     }
133 }
134 @end

运行结果,如下图:

创建控制器

一般来说,你会创建一个NSFetchedResultsController实例作为tableview的成员变量。初始化的时候,你提供四个参数:

1。 一个fetchrequest.必须包含一个sortdescriptor用来给结果集排序。

2。 一个managedobject context。 控制器用这个context来执行取数据的请求。

3。 一个可选的keypath作为sectionname。控制器用keypath来把结果集拆分成各个section。(传nil代表只有一个section)

4。 一个cachefile的名字,用来缓冲数据,生成section和索引信息。

案例中:代码解析

使用fethedRequestController控制器获取数据,此处使用懒加载的方式读取数据:

_fetchedRC = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:self.managedObjectContent sectionNameKeyPath:nil cacheName:@"book"];

参数解析:

参数1 :使用之前需通过NSFetchRequest进行读取数据,然后对request进行排序操作(必须排序你懂不?不排序就出错)。

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Book class])];
        //初始化fetchedRC必须要排序
        request.fetchBatchSize = 20;
        NSSortDescriptor *priceSort = [NSSortDescriptor sortDescriptorWithKey:@"price" ascending:YES];

[request setSortDescriptors:@[priceSort]];

参数2:由于managedObjectContent是在Applelegate.h文件中,如果想要使用,需通过Application协议创建新的managedObjectContent。

//获取应用程序代理
    AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
    //如果要对上下文内容进行修改,可managedObjectContent存在于Appdelegate中,须通过协议进行引用。

self.managedObjectContent = appDelegate.managedObjectContext;

参数3:在tableView中如果不准备进行分组显示,可以将值设为:nil;

参数4:设置缓存。

时间: 2024-10-29 19:11:17

NSFetchedResultController与UITableView的相关文章

iOS开发——项目实战总结&amp;UITableView性能优化与卡顿问题

UITableView性能优化与卡顿问题 1.最常用的就是cell的重用, 注册重用标识符 如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell 如果有很多数据的时候,就会堆积很多cell.如果重用cell,为cell创建一个ID 每当需要显示cell 的时候,都会先去缓冲池中寻找可循环利用的cell,如果没有再重新创建cell 2.避免cell的重新布局 cell的布局填充等操作 比较耗时,一般创建时就布局好 如可以将cell单独放到一个自定义类,初始化时就布局好

iOS开发tips-神奇的UITableView

概述 UITableView是iOS开发中使用频率最高的UI控件,在前面的文章中对于UITableView的具体用法有详细的描述,今天主要看一些UITableView开发中的常见一些坑,这些坑或许不深,但是如果开发中注意不到的话往往比较浪费时间. 神奇的section header 事情的起因是一个网友说要实现一个类似下图界面,但是不管是设置sectionHeaderHeight还是代理方法中实现func tableView(_ tableView: UITableView, heightFor

ios UISearchDisplayController 实现 UITableView 搜索功能

UISearchDisplayController 是苹果专为 UITableView 搜索封装的一个类. 里面内置了一个 UITableView 用于显示搜索的结果.它可以和一个需要搜索功能的 controller 关联起来,其它的像原 TableView 和搜索结果 TableView 的切换, mask 的显示等等都 封装好了,使用起来非常非常的简单.特别是要实现全屏搜索时使用最多. 全屏搜索的意思是如果你用了  NavigationBar 当点击搜索框时 TableView 会自动弹上去

iOS开发——仿Clear纯手势操作的UITableView

前言 在Clear应用中,用户无需任何按钮,纯靠不同的手势就可以完成对ToDoItem的删除.完成.添加.移动.具体来说,功能上有左划删除,右划完成,点击编辑,下拉添加.捏合添加.长按移动.这里将这些功能实现并记录. 左划删除与右划完成 所谓的左右滑动,就是自定义一个cell然后在上面添加滑动手势.在处理方法中计算偏移量,如果滑动距离超过cell宽度一半,就删除它,或者是为文本添加删除线等来完成它:如果没有超过一半,那么就用动画把cell归位. 效果图如下: 关键代码如下: - (void)ha

iOS UITableView表视图(1)

//在.h文件中声明一下 //例如:@property(nonatomic,strong)UITableView *table; //创建一个UITableView self.table = [[UITableView alloc] initWithFrame:self.bounds style:(UITableViewStylePlain)]; //设置行的高度 self.table.rowHeight = 260.0; //设置分割线的颜色 self.table.separatorColor

UITableView

1.如何设置tableview  每行之间的分割线 self.table.separatorStyle=UITableViewCellSeparatorStyleSingleLine; 2.如何让cell 能够响应 select,但是选中后的颜色又不发生改变呢,那么就设置 法一:完全不变色 cell.selectionStyle  =  UITableViewCellSelectionStyleNone: 法二:变下色马上恢复 [tableView deselectRowAtIndexPath:

iOS开发UI篇—UITableview控件基本使用

一.一个简单的英雄展示程序 NJHero.h文件代码(字典转模型) 1 #import <Foundation/Foundation.h> 2 3 @interface NJHero : NSObject 4 /** 5 * 头像 6 */ 7 @property (nonatomic, copy) NSString *icon; 8 /** 9 * 名称 10 */ 11 @property (nonatomic, copy) NSString *name; 12 /** 13 * 描述 1

iOS开发UI篇—UITableview控件简单介绍

一.基本介绍 在众多移动应?用中,能看到各式各样的表格数据 . 在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView,UITableView继承自UIScrollView,因此支持垂直滚动,?且性能极佳 . UITableview有分组和不分组两种样式,可以在storyboard或者是用代码设置. 二.数据展示 UITableView需要?一个数据源(dataSource)来显示数据UITableView会向数据源查询一共有多少行数据以及每?行显示什么数据等 没有设置数据源

iOS 中UITableView的深理解

例如下图:首先分析一下需求:1.根据模型的不同状态显示不同高度的cell,和cell的UI界面. 2.点击cell的取消按钮时,对应的cell首先要把取消按钮隐藏掉,然后改变cell的高度. 根据需求先解决第一个需求,需要两步 当模型数据的属性的status [email protected]"2",不显示取消按钮:status = @"1",显示取消按钮. 1.需要注意的是cell的重用在这里面互有一些影响,所以在自定义cell的模型的setter方法中, 在ce