如何在由Core Data / NSFetchedResultsController支持的UITableView顶部插入新对象? [英] How can I insert new objects at top of UITableView backed by Core Data/NSFetchedResultsController?

查看:127
本文介绍了如何在由Core Data / NSFetchedResultsController支持的UITableView顶部插入新对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个tableview是成功地纳入NSFetchedResultsController。但是,我需要我的tableview中最顶端的单元格读取添加新对象,并有UITableViewCellEditingStyleInsert,而不是默认的UITableViewCellEditingStyleDelete。



FetchResultsController想检查managedObjectContext对象 - 确定行数和填充表单元格。我想到的唯一的方法是创建一个虚拟对象,但我觉得应该有一个更优雅的解决方案。



UPDATE:



对于那些可能对我最终得到什么解决方案很好奇的人,我决定让我的插入单元格在底部而不是顶部。下面是相关代码:

   - (void)viewDidLoad {
[super viewDidLoad];

//取消注释以下行以保留演示文稿之间的选择。
//self.clearsSelectionOnViewWillAppear = NO;

self.editing = YES;
self.tableView.allowsSelectionDuringEditing = YES;
self.tableView.delegate = self;

RubricAppDelegate * appDelegate =(RubricAppDelegate *)[[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
NSEntityDescription * entity = [NSEntityDescription entityForName:@myClassinManagedObjectContext:managedObjectContext];
NSFetchRequest * request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entity];

NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@classIDascending:YES];
NSArray * sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];

fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil cacheName:nil];
NSError * error;
[fetchedResultsController performFetch:& error];

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@Number of sections =%d,[[fetchedResultsController sections] count]

return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//返回节中的行数。
id< NSFetchedResultsSectionInfo> myClass = [[fetchedResultsController sections] objectAtIndex:section];
NSLog(@Number of classes =%d,[myClass numberOfObjects]);

return([[fetchedResultsController fetchedObjects] count] + 1);

}

//自定义表视图单元格的外观。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString * CellIdentifier = @Cell;

UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

NSLog(@FRC count + 1 =%d,([[fetchedResultsController fetchedObjects] count] + 1));

if(indexPath.row ==([[fetchedResultsController fetchedObjects] count])){
cell.textLabel.text = @添加新类;
}
else {
myClass * theClass = [fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@类名是:%@,theClass.classTitle);
cell.textLabel.text = theClass.classTitle;
}


return cell;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == [[fetchedResultsController fetchedObjects] count]){
return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleDelete;
}

结果(含一些垃圾数据):





现在我唯一的问题是让删除功能正常工作。您可以关注此问题的相关文章这里



您可以通过更改 -tableView:numberOfRowsInSection:和 -tableView:cellForRowAtIndexPath:方法来调整单元格计数并进行调整。所以你的 -tableView:numberOfRowsInSection:会返回N + 1,你的 -tableView:cellForRowAtIndexPath: -1除非N == 0,那么它将返回你的添加新对象单元格。



没有必要搞砸核心数据元素,因为这是严格一个UI问题。



更新




但现在我不知道返回我获取的对象的计数(假设是我在上面的答案中使用的N)。此外,我不会希望-tableView:cellForRowAtIndexPath返回我的添加新对象单元格时,indexPath.row =(N + 1),而不是N = 0?我可能会误解N是什么意思,但我认为这只是指被抓取的对象的数量。


是它是实际对象的计数。



您确实希望您的 -tableView:cellForRowAtIndexPath:返回您的添加新对象是点?您只需要返回不同的类型的单元格。



您在此解决方案中所做的是添加一个不是 NSFetchedResultsController 一部分的单元格,然后补偿当您从 NSFetchedResultsController 中检索实际对象时以及用户选择单元格时。


I have a tableview that is successfully incorporating an NSFetchedResultsController. However, I need the topmost cell in my tableview to read, "Add new object" and have UITableViewCellEditingStyleInsert instead of the default UITableViewCellEditingStyleDelete.

The FetchResultsController wants to check the managedObjectContext for objects--both to determine number of rows and to populate the table cells. The only way I can think to get around this is to create a dummy object, but I feel like there ought to be a more elegant solution.

UPDATE:

For those who might be curious as to what solution I ended up with, I decided to have my insert cell at the bottom, not the top. Here is the relevant code:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    //self.clearsSelectionOnViewWillAppear = NO;

    self.editing = YES;
    self.tableView.allowsSelectionDuringEditing = YES;
    self.tableView.delegate = self;

    RubricAppDelegate *appDelegate = (RubricAppDelegate *)[[UIApplication sharedApplication] delegate];
    managedObjectContext = [appDelegate managedObjectContext];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"myClass" inManagedObjectContext:managedObjectContext];
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"classID" ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    [request setSortDescriptors:sortDescriptors];
    [sortDescriptor release];

    fetchedResultsController = [[NSFetchedResultsController alloc]
                                               initWithFetchRequest:request 
                                               managedObjectContext:self.managedObjectContext
                                               sectionNameKeyPath:nil cacheName:nil];
    NSError *error;
    [fetchedResultsController performFetch:&error];

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSLog(@"Number of sections = %d", [[fetchedResultsController sections] count]);

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    id <NSFetchedResultsSectionInfo> myClass = [[fetchedResultsController sections] objectAtIndex:section];
    NSLog(@"Number of classes = %d", [myClass numberOfObjects]);

    return ([[fetchedResultsController fetchedObjects] count] + 1);

}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    NSLog(@"FRC count + 1 = %d", ([[fetchedResultsController fetchedObjects] count] + 1));

    if (indexPath.row == ([[fetchedResultsController fetchedObjects] count])) {
        cell.textLabel.text = @"Add New Class";
    }
    else {
        myClass *theClass = [fetchedResultsController objectAtIndexPath:indexPath];
        NSLog(@"Class name is: %@", theClass.classTitle);
        cell.textLabel.text = theClass.classTitle;
    }


    return cell;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == [[fetchedResultsController fetchedObjects] count]) {
        return UITableViewCellEditingStyleInsert;
    }
    return UITableViewCellEditingStyleDelete;
}

The result (with some junk data):

Now my only issue is getting the delete functions to work properly. You can follow my post on that issue here

解决方案

Normally the add row is at the bottom.

You can accomplish this by changing the -tableView:numberOfRowsInSection: and the -tableView:cellForRowAtIndexPath: methods to adjust the cell count and adjust for it. So your -tableView:numberOfRowsInSection: would return N+1 and your -tableView:cellForRowAtIndexPath: would get object at N-1 unless N == 0 then it would return your "Add new object" cell.

There is no need to mess with the underlying Core Data elements as this is strictly a UI issue.

Update

But now I'm not sure how to return the count of my fetched objects (assuming that is what I used for "N" in your above answer). Also, wouldn't I want -tableView:cellForRowAtIndexPath to return my "Add new object" cell when the indexPath.row = (N + 1), not N = 0? I may be misunderstanding what "N" equates to, but I thought it just meant count of fetched objects.

Yes it is the count of actual objects.

You do want your -tableView:cellForRowAtIndexPath: to return a cell for your "Add new object" otherwise what is the point? You just want it to return a different type of cell.

All you are doing in this solution is adding a cell that is not part of the NSFetchedResultsController and then compensating for it when you are retrieving an actual object from the NSFetchedResultsController and when the user selects a cell.

这篇关于如何在由Core Data / NSFetchedResultsController支持的UITableView顶部插入新对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆