当NSPredicate设置时,UITableView不刷新 [英] UITableView doesn't refresh when NSPredicate set
问题描述
前言:我尝试了 [self.tableview reloadData]
。我的应用程序不会崩溃,但它不刷新,无论。
我试图在一个 TableViewController
上显示两组结果,具体取决于 NSPredicate
设置。我试图找到一个行话的免费答案我如何更新一个 UITableViewController
一旦一个谓词设置。
我的数据正确显示视图最初加载的时间。我的谓词设置正确,所有的日志语句我抛出的返回值...但是没有什么发生,当它设置。
我知道这是一个非常愚蠢的问题,但我太蠢了。我发现的每个答案涉及到一个 UISearchBar
,不推荐使用的方法,或者是一个答案的片段等。
我想显示的内容:
1)显示所有内容的vanilla fetchRequest:在我的managedObjectContext中的一切都在我的 viewDidLoad
w / o an NSPredicate
中设置。
2)一旦我设置了 NSPredicate
,我想更新 tableView
- 这不会崩溃,但它不会更新 tableView
On MyTableViewController
,我有一个popover,当我点击一个UIBarButtonItem在MyTableViewController实例化。在弹出窗口中,我在MyTableViewController上设置一个谓词。
基本上,我想切换显示的内容,显示切换是由我的变量是nil显示)或过滤(变量设置谓词)。
我是第一个或最蠢的人尝试这个软件工程专长。我会打赌后者,因为我看到这是一个最终用户多少次。 如果您知道我在做什么,我们非常感谢您的回复。非常感谢您阅读。
我有两个实体: PointOfInterest
和 LocationCategory
。我有一个 UIBarButton
触发一个弹出窗口,其中 MyTableViewController
是一个委托。点击弹出窗口在 MyTableViewController
上设置 selectedCategory
属性:
//这由PopoverTableViewController设置
@property(nonatomic,strong)LocationCategory * selectedCategory;
//这是在`MyTableViewController`上设置的
@property(nonatomic,strong)NSPredicate * searchPredicate;
属性在 MyTableViewController
上正确设置。我试图使用 selectedCategory
对象作为谓词显示过滤列表的pointOfInterest对象的基础。我从这个 TVC
中省去了样板代码,但是我有 TVC
上的tableView委托方法。 / p>
我想我需要设置我的 fetchedResultsController
为nil并重新赋予它在我的 refreshTableViewController
方法。它不会崩溃,但它不工作。
这是 viewDidLoad
的 MyTableViewController
:
- (void)viewDidLoad {
[super viewDidLoad] ;
AppDelegate * appDelegate = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectContext;
//取消注释以下行以保留演示文稿之间的选择。
// self.clearsSelectionOnViewWillAppear = NO;
NSLog(@savedPOI managedObjectContext is%@,self.managedObjectContext);
//初始化获取请求
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@PointOfInterest];
//添加排序描述符
[fetchRequest setSortDescriptors:@ [[NSSortDescriptor sortDescriptorWithKey:@nameascending:YES]]];
//初始化获取的结果控制器
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
//配置fetchedResultsController
[self.fetchedResultsController setDelegate:self];
//执行fetch
NSError * error = nil;
[self.fetchedResultsController performFetch:& error];
if(错误){
NSLog(@无法执行提取);
NSLog(@%@,%@,error,error.localizedDescription);
}
//设置一个观察者监听`selectedCategory`的设置
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshTableViewController :) name :@CategorySelectedobject:nil];
}
一旦我的 selectedCategory
设置,我有以下方法设置运行。它不会崩溃,但它不刷新 MyTableViewController
。我怀疑我在这里有一个小错误,但我不知道我做错了什么。
- void)refreshTableViewController:(NSNotification *)notification {
if([[notification name] isEqualToString:@CategorySelected]){
NSLog(@NSNotification on SavedPOITableViewController's self.selectedCategory is%@ .selectedCategory.categoryName);
// Nuke在viewDidLoad
中加载的缓存[NSFetchedResultsController deleteCacheWithName:@PointOfInterest];
//在viewDidLoad中调用fetchedResultsController alloc / inited
self.fetchedResultsController = nil;
//分配一个新的fetchRequest
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
//设置实体
NSEntityDescription * entity = [NSEntityDescription entityForName:@PointOfInterestinManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
//添加排序描述符
[fetchRequest setSortDescriptors:@ [[NSSortDescriptor sortDescriptorWithKey:@nameascending:YES]]];
//重新获取fetchedResultsController
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
NSString * predicateString = self.selectedCategory.categoryName;
NSLog(@predicateString is%@,predicateString);
self.searchPredicate = [NSPredicate predicateWithFormat:@locationCategory.categoryName ==%@,predicateString];
NSLog(@self.searchPredicate in refreshTableViewController is%@,predicateString);
//使用谓词
[fetchRequest setPredicate:self.searchPredicate]来执行fetchRequest;
//执行fetch
NSError * error = nil;
[self.fetchedResultsController performFetch:& error];
if(错误){
NSLog(@无法执行提取);
NSLog(@%@,%@,error,error.localizedDescription);
}
[self.tableView reloadData];
}
}
仅仅为了完整性'缘,这里是我的 PointOfInterest
& LocationCategory
classs:
#import< Foundation / Foundation.h>
#import< CoreData / CoreData.h>
@class LocationCategory;
@interface PointOfInterest:NSManagedObject
@property(nonatomic,retain)NSString * note;
@property(nonatomic,retain)NSString * name;
@property(nonatomic,retain)NSString * address;
@property(nonatomic,retain)NSNumber * latitude;
@property(nonatomic,retain)NSNumber * longitude;
@property(nonatomic,retain)NSString * phoneNumber;
@property(nonatomic,retain)NSString * url;
@property(nonatomic,retain)LocationCategory * locationCategory;
#import< Foundation / Foundation.h>
#import< CoreData / CoreData.h>
@class PointOfInterest;
@interface LocationCategory:NSManagedObject
@property(nonatomic,retain)id categoryColor;
@property(nonatomic,retain)NSString * categoryName;
@property(nonatomic,retain)NSSet * pointOfInterest;
@end
我将其添加到 MyTableViewController
上的实现文件中:
@synthesize fetchedResultsController = _fetchedResultsController;
正如我预期的,我错过了一些惊人的愚蠢 - 和 !!
我在Ray Wenderlich的网站上看到这篇文章,我注意到它在实现中有这行,但我没有。我从来没有遇到过需要使用 @synthesize
,我已经看到在别的地方,你几乎从不需要它等,好吧,结果,你做!
http://www.raywenderlich.com/14742/core-data-on-ios-5-tutorial-how-to-work-with-relations-and-谓词
StackOverflow上的这篇文章介绍了 @synthesize
的基本知识。
Preface: I tried [self.tableview reloadData]
. My app doesn't crash, but it doesn't refresh, either.
I'm trying to display 2 sets of results on one TableViewController
depending upon whether an NSPredicate
is set. I'm trying to find a jargon free answer how I can update a UITableViewController
once a predicate is set.
My data displays properly the when the view initially loads. My predicate sets properly, all the log statements I've thrown in return values...but nothing happens when it's set.
I know this is a startlingly stupid question, but I'm too dumb figure it out. Every answer I've found involves a UISearchBar
, deprecated methods, or is a snippet of an answer, etc.
What I'd like to display:
1) A vanilla fetchRequest that displays everything--this works: everything in my managedObjectContext which is set up in my viewDidLoad
w/o an NSPredicate
.
2) Once I set an NSPredicate
, I'd like to update the tableView
--This doesn't crash, but it doesn't update the tableView
On MyTableViewController
, I have a popover which instantiates when I click a UIBarButtonItem on MyTableViewController. On the popover, I set a predicate on MyTableViewController.
Basically, I'd like to toggle what's displayed and that display toggle is driven by whether my variable is nil (everything displays) or filtered (variable sets a predicate).
I'm either the first or the dumbest person to attempt this feat of software engineering. I'll wager the latter, given how many times I've seen this as an end-user. If you know what I'm doing wrong, I'd be grateful to hear from you. Thank you for reading.
I have two entities: PointOfInterest
and LocationCategory
. I have a UIBarButton
that triggers a popover of which MyTableViewController
is a delegate. Clicking on the popover sets the selectedCategory
property on MyTableViewController
.:
// This gets set by PopoverTableViewController
@property (nonatomic, strong) LocationCategory *selectedCategory;
// This is set on `MyTableViewController`
@property (nonatomic, strong) NSPredicate *searchPredicate;
The property gets set correctly on MyTableViewController
. I'm trying to use the selectedCategory
object as the basis for a predicate to display "filtered" list of 'pointOfInterest' objects. I left out the boilerplate code from this TVC
, but I've got the tableView delegate methods on the TVC
.
I think I need to set my fetchedResultsController
to nil and reinstantiate it w/ a predicate in my refreshTableViewController
method. It doesn't crash, but it doesn't work, either.
Here's the viewDidLoad
of MyTableViewController
:
- (void)viewDidLoad {
[super viewDidLoad];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectContext;
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
NSLog(@"savedPOI managedObjectContext is %@", self.managedObjectContext);
// Initialize fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]initWithEntityName:@"PointOfInterest"];
// Add sort descriptors
[fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]];
// Initialize Fetched Results Controller
self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
// Configure a fetchedResultsController
[self.fetchedResultsController setDelegate:self];
// Perform fetch
NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
if (error) {
NSLog(@"Unable to perform fetch");
NSLog(@"%@, %@", error, error.localizedDescription);
}
// This sets up an observer that listens for when `selectedCategory` is set
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(refreshTableViewController:) name:@"CategorySelected" object:nil];
}
Once my selectedCategory
is set, I have the following method set to run. It doesn't crash, but it doesn't refresh MyTableViewController
. I suspect I've got a minor error here, but I'm not sure what I'm doing wrong.
- (void)refreshTableViewController:(NSNotification *)notification {
if ([[notification name]isEqualToString:@"CategorySelected"]) {
NSLog(@"NSNotification on SavedPOITableViewController's self.selectedCategory is %@", self.selectedCategory.categoryName);
// Nuke the cache that was loaded in viewDidLoad
[NSFetchedResultsController deleteCacheWithName:@"PointOfInterest"];
// Nuke the fetchedResultsController alloc/inited in viewDidLoad
self.fetchedResultsController = nil;
// Alloc init a new fetchRequest
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Set the entity
NSEntityDescription *entity = [NSEntityDescription entityForName:@"PointOfInterest" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Add sort descriptors
[fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]];
// Reinstantiate the fetchedResultsController
self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
NSString *predicateString = self.selectedCategory.categoryName;
NSLog(@"predicateString is %@", predicateString);
self.searchPredicate = [NSPredicate predicateWithFormat:@"locationCategory.categoryName == %@", predicateString];
NSLog(@"self.searchPredicate in refreshTableViewController is %@", predicateString);
// Do the fetchRequest with the predicate
[fetchRequest setPredicate:self.searchPredicate];
// Perform fetch
NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
if (error) {
NSLog(@"Unable to perform fetch");
NSLog(@"%@, %@", error, error.localizedDescription);
}
[self.tableView reloadData];
}
}
Just for completeness' sake, here's my PointOfInterest
& LocationCategory
classs:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class LocationCategory;
@interface PointOfInterest : NSManagedObject
@property (nonatomic, retain) NSString * note;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSNumber * latitude;
@property (nonatomic, retain) NSNumber * longitude;
@property (nonatomic, retain) NSString * phoneNumber;
@property (nonatomic, retain) NSString * url;
@property (nonatomic, retain) LocationCategory *locationCategory;
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class PointOfInterest;
@interface LocationCategory : NSManagedObject
@property (nonatomic, retain) id categoryColor;
@property (nonatomic, retain) NSString * categoryName;
@property (nonatomic, retain) NSSet *pointOfInterest;
@end
I figured it out:
I added this to my implementation file on MyTableViewController
:
@synthesize fetchedResultsController = _fetchedResultsController;
As I expected, I was missing something startlingly stupid--and I was **RIGHT!!
I read this post on Ray Wenderlich's website and I noticed it had that line in the implementation, but I didn't. I've never encountered the need to use @synthesize
and I've seen mentions elsewhere that "you almost never need it", etc. Well, turns out, you do!
This post on StackOverflow covers the basics of @synthesize
.
What exactly does @synthesize do?
这篇关于当NSPredicate设置时,UITableView不刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!