I have a problem with my TableViewController. There is a custom cell, with a class, and various infos dynamically loaded. My TableViewController appears, but my cell doesn't display, but i can touch this, and my transition with infos are good.
Thanks for your answers.
TableViewController.m
#interface Chat() {
NSMutableArray *messages;
UIRefreshControl *refreshControl;
}
#property (strong, nonatomic) IBOutlet UITableView *tableMessages;
#end
#implementation Chat
NSString *cellIdentifier = #"ChatCell";
- (void)viewDidLoad {
[super viewDidLoad];
[_tableMessages registerClass:[ChatCell class] forCellReuseIdentifier:cellIdentifier];
refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(loadMessages) forControlEvents:UIControlEventValueChanged];
[_tableMessages addSubview:refreshControl];
messages = [[NSMutableArray alloc] init];
[self loadMessages];
}
- (void)loadMessages {
if ([PFUser currentUser] != nil)
{
PFQuery *query = [PFQuery queryWithClassName:PF_MESSAGES_CLASS_NAME];
[query whereKey:PF_MESSAGES_USER equalTo:[PFUser currentUser]];
[query includeKey:PF_MESSAGES_LASTUSER];
[query orderByDescending:PF_MESSAGES_UPDATEDACTION];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error == nil) {
[messages removeAllObjects];
[messages addObjectsFromArray:objects];
[_tableMessages reloadData];
} else [ProgressHUD showError:#"Network error."];
[refreshControl endRefreshing];
}];
}
}
- (void)actionCleanup {
[messages removeAllObjects];
[_tableMessages reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [messages count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ChatCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
[cell bindData:messages[indexPath.row]];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
DeleteMessageItem(messages[indexPath.row]);
[messages removeObjectAtIndex:indexPath.row];
[_tableMessages deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
PFObject *message = messages[indexPath.row];
ChatView *chatView = [[ChatView alloc] initWith:message[PF_MESSAGES_ROOMID]];
[self.navigationController pushViewController:chatView animated:YES];
}
#end
TableViewCell.m
#interface ChatCell() {
PFObject *message;
}
#end
#implementation ChatCell
- (void)bindData:(PFObject *)message_ {
message = message_;
_chatImg.layer.cornerRadius = _chatImg.frame.size.width/2;
_chatImg.layer.masksToBounds = YES;
PFUser *lastUser = message[PF_MESSAGES_LASTUSER];
[_chatImg setFile:lastUser[PF_USER_PICTURE]];
[_chatImg loadInBackground];
_chatUsername.text = message[PF_MESSAGES_DESCRIPTION];
_chatMessage.text = message[PF_MESSAGES_LASTMESSAGE];
NSTimeInterval seconds = [[NSDate date] timeIntervalSinceDate:message.updatedAt];
_chatDate.text = TimeElapsed(seconds);
}
#end
It's because you register the cell using - registerClass:forCellReuseIdentifier:.
If you register it this way you have to construct the view programmatically or load the nib file in ChatCell code.
To solve the problem, do either of these:
Create a nib file containing the view for your table view cell and set the class to ChatCell. Then use - registerNib:forCellReuseIdentifier: to register the nib.
Construct the view programmatically eg. create a UILabel and add it as a subview of ChatCell.
Make the prototype cell in the storyboard and set the cell identifier to ChatCell. Then remove the - registerClass:forCellReuseIdentifier:
Check You are given correct cell Identifier in storyboard. (case sensitive) " ChatCell"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"ChatCell";
ChatCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
[cell bindData:messages[indexPath.row]];
return cell;
}
You are updating the UI on background thread. Try this, in your "loadMessages" method.
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
//update UI here
if (error == nil) {
[messages removeAllObjects];
[messages addObjectsFromArray:objects];
[_tableMessages reloadData];
} else [ProgressHUD showError:#"Network error."];
[refreshControl endRefreshing];
});
}];
Related
I want to be able to display all of the data from two classes from Parse.com but it is not working. Every time I go to open the tableview the app crashes. Here is my code. I used the guidance from https://www.parse.com/questions/query-with-two-classes to aid me.
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
// This table displays items in the class
self.parseClassName = #"rep";
self.parseClassName = #"rep2";
self.pullToRefreshEnabled = YES;
self.paginationEnabled = NO;
self.objectsPerPage = 100;
}
return self;
}
- (PFQuery *)queryForTable {
PFQuery *1query = [PFQuery queryWithClassName:#"rep"];
PFQuery *2query = [PFQuery queryWithClassName:#"rep2"];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[1query,2query]];
[query whereKey:#"user" equalTo:[PFUser currentUser]];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
}];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
}
// Configure the cell to show todo item with a priority at the bottom
cell.textLabel.text = [object objectForKey:#"name"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Username: %#",
[object objectForKey:#"username"]];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove the row from data model
PFObject *objectToDel = [self.objects objectAtIndex:indexPath.row];
[objectToDel deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
UIAlertView *Alert = [[UIAlertView alloc] initWithTitle:#"Item Was Deleted Successfully. Pull Down to Refresh Tab" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[Alert show];
}
];
}
#end
> Specwatch[668:192464] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'All sub queries of an
> `or` query should be on the same class.'
> *** First throw call stack:
> (0x182319900 0x181987f80 0x182319848 0x1000bd8b4 0x100025c10 0x100072514 0x100071e00 0x18700c0c0 0x1870cbda8 0x1870cbc80
> 0x1870caec8 0x1870caa6c 0x1870ca694 0x1870ca5fc 0x187007778
> 0x184a16b2c 0x184a11738 0x184a115f8 0x184a10c94 0x184a109dc
> 0x184a0a0cc 0x1822d0588 0x1822ce32c 0x1822ce75c 0x1821fd680
> 0x18370c088 0x187074d90 0x10006d054 0x181d9e8b8)
> libc++abi.dylib: terminating with uncaught exception of type NSException
> (lldb)
I'll try to summarize how to go about emancipating yourself from the PFQueryTableViewController (and UITableViewController for that matter. The world would be a slightly happier place if neither of these classes had been invented (imo)). Create a UIViewController subclass called ViewController.
In IB, add a UIViewController (setting its class to ViewController), give it a UITableView constrained to the edges of the view. Hook up the datasource, delegate and an outlet called tableView. Add a prototype cell. For now, just use a standard subtitle or left detail UITableViewCell. Give the cell an identifier of #"cell".
// viewcontroller.m
#interface ViewController () <UITableViewDataSource, UITableViewDelegate>
#property(weak,nonatomic) IBOutlet UITableView *tableView;
#property(strong,nonatomic) NSMutableArray *objects;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[PFCloud callFunctionInBackground:#"getTwoClasses" withParameters:nil block:^(NSArray *objects, NSError *error) {
self.objects = objects;
[self.tableView reloadData];
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
PFObject *object = self.objects[indexPath.row];
cell.textLabel.text = [object objectId];
cell.detailTextLabel.text = [object parseClassName];
return cell;
}
That very simple implementation should be all that's needed on the client. On the server, we just need a cloud function called "getTwoClasses" to get objects from two classes (rep and rep2).
Deploy this function to do that...
Parse.Cloud.define("getTwoClasses", function(request, response) {
var reps;
var user = request.user;
var repQuery = new Parse.Query("rep");
repQuery.equalTo("user", user);
query.find().then(function(result) {
reps = result;
var rep2Query = new Parse.Query("rep2");
rep2Query.equalTo("user", user);
return rep2Query.find();
}).then(function(result) {
response.success(reps.concat(result));
}, function(error) {
response.error(error);
});
});
I have been stuck on this all day and I'm looking for some help. I am making an app where someone can type in a web address that web address will be stored in a table view. When the user taps on that cell it will take them to the web view where they can view that site. I am using parse as my backend to store the user input. ( I am not using PFQueryTableView)
Here is my code for the tableViewController:
interface MenuTableViewController : UITableViewController
#property(strong, nonatomic) NSMutableArray *referralArray;
#property (strong, nonatomic) PFObject *selectLink;
#property (nonatomic, strong) NSArray *webInput;
#property (nonatomic, strong) UIRefreshControl *refreshControl;
#end
#interface MenuTableViewController ()
#end
#implementation MenuTableViewController
#synthesize referralArray;
- (void)viewDidLoad
{
[super viewDidLoad];
PFUser *currentUser = [PFUser currentUser];
if (currentUser) {
NSLog(#"Current user: %#", currentUser.username);
}
else {
[self performSegueWithIdentifier:#"showLogin" sender:self];
}
//refresh inbox
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(retrieveMessages) forControlEvents:UIControlEventValueChanged];
//swipe to delete
self.tableView.allowsMultipleSelectionDuringEditing = NO;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController.navigationBar setHidden:NO];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.webInput count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"refCell"forIndexPath:indexPath];
PFObject *web = [self.webInput objectAtIndex:indexPath.row];
cell.textLabel.text = [web objectForKey:#"RefLink"];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.selectLink = [self.webInput objectAtIndex:indexPath.row];
//NSString *fileType = [self.selectLink objectForKey:#"RefLink"];
//[self performSegueWithIdentifier:#"webSegue" sender:self];
NSDictionary *dict = [self.webInput objectAtIndex:indexPath.section];
NSString *link=[dict valueForKey:#"link"];
//Create a URL object.
NSURL *url = [NSURL URLWithString:link];
UINavigationController *nav = [self.storyboard instantiateViewControllerWithIdentifier:#"WebView"];
WebViewController *web = (WebViewController *)nav.topViewController;
web.webLink =url;
}
//swipe to delete
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//try this
PFObject *object = [self.webInput objectAtIndex:indexPath.row];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[self refreshControl];
[self.tableView reloadData];
}];
}
}
#pragma mark - Helper methods
- (void)retrieveMessages {
PFQuery *query = [PFQuery queryWithClassName:#"Referrals"];
//[query whereKey:#"recipientIds" equalTo:[[PFUser currentUser] objectId]];
//run the query here for messages
[query orderByDescending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
else {
// We found messages!
self.webInput = objects;
[self.tableView reloadData];
NSLog(#"Retrieved %lu messages", (unsigned long)[self.webInput count]);
}
if ([self.refreshControl isRefreshing]) {
[self.refreshControl endRefreshing];
}
}];
}
#pragma mark - LogOut
- (IBAction)logout:(id)sender {
[PFUser logOut];
[self performSegueWithIdentifier:#"showLogin" sender:self];
}
#pragma mark - Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showLogin"]) {
[segue.destinationViewController setHidesBottomBarWhenPushed:YES];
}
else if ([segue.identifier isEqualToString:#"webSegue"]) {
[segue.destinationViewController setHidesBottomBarWhenPushed:YES];
WebViewController *webView = (WebViewController *)segue.destinationViewController;
webView.webAddress = self.selectLink;
}
}
#end
If Someone could help me out I would greatly appreciate it!
I'm trying to do a search function in my table view, to return objects from my Parse.com class.
I'm getting this error when I try to make a search in the UISearchBar:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier FeaturedTableViewCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
Here's how I'm doing it:
#interface DiscoverViewController () <UISearchBarDelegate, UISearchDisplayDelegate>
#property (nonatomic, retain) PFQuery *query;
#property (nonatomic, retain) PFObject *category;
#end
#implementation DailyDiscoverViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
self.searchController.delegate = self;
self.searchResults = [NSMutableArray array];
_categories = [[NSMutableArray alloc] initWithCapacity:100];
}
- (void)filterResults:(NSString *)searchTerm {
[self.searchResults removeAllObjects];
PFQuery *query = [PFQuery queryWithClassName:#"Projects"];
[query whereKeyExists:#"name"];
[query whereKey:#"name" containsString:searchTerm];
NSArray *results = [query findObjects];
[self.searchResults addObjectsFromArray:results];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterResults:searchString];
return YES;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
}
- (void)refresh {
PFQuery *query = [PFQuery queryWithClassName:#"Categories"];
[query orderByDescending:#"name"];
[query findObjectsInBackgroundWithBlock:^(NSArray *posts, NSError *error) {
if (!error) {
//NSLog(#"%#", posts);
} else {
}
[_categories setArray:posts];
[self.tableView reloadData];
[_loadingView stopAnimating];
[_refreshControl endRefreshing];
}];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.tableView) {
if (section == 0) {
return 1;
} else {
return self.categories.count;
}
} else {
return self.searchResults.count;
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return 320;
} else {
return 52;
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
_featuredObject = [_featured objectAtIndex:indexPath.row];
DiscoverFeaturedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DiscoverFeaturedTableViewCell" forIndexPath:indexPath];
[(PFFile*)_featuredObject[#"picture"] getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
cell.image1.image = [UIImage imageWithData:data];
}];
return cell;
} else {
_category = [_categories objectAtIndex:indexPath.row];
DiscoverTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DiscoverTableViewCell" forIndexPath:indexPath];
cell.name.text = _category[#"name"];
if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]) {
PFUser *obj2 = [self.searchResults objectAtIndex:indexPath.row];
PFQuery *query = [PFQuery queryWithClassName:#"Projects"];
PFObject *searchedUser = [query getObjectWithId:obj2.objectId];
NSString *first = [searchedUser objectForKey:#"name"];
cell.name.text = [first substringToIndex:1];
cell.name.text = first;
return cell;
}
return cell;
}
}
#end
I think you can look this stack over flow post : POST
K.
Ok,
Try it on viewDidLoad:
YourCustomCell *yourCustomCell = [UINib
nibWithNibName:#"YourCustomCell" bundle:nil]; [self.tableView
registerNib:cellNib forCellReuseIdentifier:#"cell"];
Note: Your custom cell must have a .xib of course.
You could try this, I remember running into this exact issue and this was one of the solutions I tried:
[self.tableView registerClass:[DiscoverTableViewCell class] forCellReuseIdentifier:#"DiscoverTableViewCell"];
However, I distinctly remember that this didn't work. It turned out I hadn't correctly connected the cells in the storyboard. Furthermore, make sure that the class of your storyboard cell has been changed to represent your cell's custom class.
I am using a PFQueryTableView to search my Parse database. Everything seems to be working fine except that when i actually search the results don't make sense. For example i have three rows with the search values(truthIsName) that are "a","ab","abc","g". When i search "g" only "abc" shows up. When i search "abc", "abc" shows up. When i search "a" it seems to work correctly and "a","ab", and "abc" show up. I can give more examples if they are needed but I believe the problem is in my filter code and I can't figure out what I'm doing wrong.
- (void)filterResults:(NSString *)searchTerm {
PFQuery *query = [PFQuery queryWithClassName: #"TruthIsData"];
[query whereKey:#"truthIsName" containsString:searchTerm];
//query.limit = 50;
[query findObjectsInBackgroundWithTarget:self
selector:#selector(callbackWithResult:error:)];
}
If you need it here is the full .m file
#import "AllDataTableViewController.h"
#import <Parse/Parse.h>
#implementation AllDataTableViewController : PFQueryTableViewController
#synthesize searchBar;
#synthesize searchController;
#synthesize searchResults;
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// The className to query on
self.className = #"TruthIsData";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"truthIsName";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = NO;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.tableHeaderView = self.searchBar;
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
self.searchController.delegate = self;
self.searchResults = [NSMutableArray array];
}
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.className];
if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [object objectForKey:#"truthIsName"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"User: %#", [object objectForKey:#"username"]];
return cell;
}
- (void)callbackWithResult:(NSArray *)objects error:(NSError *)error
{
if(!error) {
[self.searchResults removeAllObjects];
[self.searchResults addObjectsFromArray:objects];
[self.searchDisplayController.searchResultsTableView reloadData];
}
}
- (void)filterResults:(NSString *)searchTerm {
PFQuery *query = [PFQuery queryWithClassName: #"TruthIsData"];
[query whereKey:#"truthIsName" containsString:searchTerm];
//query.limit = 50;
[query findObjectsInBackgroundWithTarget:self selector:#selector(callbackWithResult:error:)];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterResults:searchString];
return YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.tableView) {
return self.objects.count;
} else {
return self.searchResults.count ;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
#end
Thanks!
After adding the line I get
TutorialBase[764:20074] Queried Objects: (
"<TruthIsData:6ikJq0hhtc:(null)> {\n truthIsName = g;\n}"
) ((null))
I am not entirely sure about the flow in your class, but it seems to me that you are not using at all the results of the query (as stored in self.searchResults).
More precisely, you are not dealing with search results in tableView:cellForRowAtIndexPath:object:. I would expect something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
if (tableView == self.tableView) {
<actual implementation here>
} else {
<similar implementation but where you get the data from self.searchResults>
}
}
(along the lines of what you do in tableView:numberOfRowsInSection:)
Actually, what I would do is overriding the cellForRowAtIndexPath: like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.tableView) {
//-- this will call into PFQueryTable and then into tableView:numberOfRowsInSection:object:
[super tableView:tableView cellForRowAtIndexPath:indexPath];
} else {
<similar implementation but where you get the data from self.searchResults>
}
}
So that you do not go into PFQueryTableView for searchResults (which are displayed in a different table view altogether).
I am not sure that it is a good idea to have the same class act both as a delegate/datasource for PFQueryTableView and UISearchDisplayController -- your code would be definitely more readable if you have a specialised class for the latter's datasource. But that is just a suggestion.
EDIT:
This is how it could look like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
if (tableView == self.tableView) {
//-- this will call into PFQueryTable and then into tableView:numberOfRowsInSection:object:
[super tableView:tableView cellForRowAtIndexPath:indexPath];
} else {
PFObject* object = self.searchResults[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [object objectForKey:#"truthIsName"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"User: %#", [object objectForKey:#"username"]];
return cell;
}
This was working fine yesterday and without touching anything it stopped working today. When I run the query to allocate my 'filterEvents' array, 'objects' in the block is empty. Anyone know what's going on?
#import "FilterViewController.h"
#interface FilterViewController ()
#end
#implementation FilterViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.filterTable.dataSource = self;
self.filterTable.delegate = self;
[self performSelector:#selector(retrieveFilteredEvents)];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.filterEvents count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"filterTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
NSDictionary *tempDict = [self.filterEvents objectAtIndex:indexPath.row];
self.eventTitle = [tempDict objectForKey:#"eventType"];
cell.textLabel.text = self.eventTitle;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *tempDict = [self.filterEvents objectAtIndex:indexPath.row];
NSString *string = [tempDict objectForKey:#"eventType"];
[self.delegate setFilter:string];
[self dismissViewControllerAnimated:YES completion:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateParent" object:nil];
}
#pragma mark - Helper Methods
- (IBAction)done:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)retrieveFilteredEvents
{
PFQuery *retrieveEvents = [PFQuery queryWithClassName:#"eventTypes"];
[retrieveEvents orderByAscending:#"eventOrder"];
[retrieveEvents findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.filterEvents = [[NSArray alloc] initWithArray:objects];
NSLog(#"%#", self.filterEvents);
}
[self.filterTable reloadData];
}];
}
#end