The fast enumeration works, and shows the memory address for my 3 objects. But a simple count on my brothersArray (brothersArray.count) comes up with 0. I'm a bit of a noob. What I am missing?
I'm not receiving any errors or warnings. Everything appears to work fine. I just can't figure out why my array.count comes up as zero. Thanks in advance!
Here is my entire MasterViewController.m
// MasterViewController.m
// Matt_Bug
//
// Created by Matthew Toto on 5/17/14.
// Copyright (c) 2014 Matthew Toto. All rights reserved.
//
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "MPTBrothers.h"
#interface MasterViewController () {
NSMutableArray *_objects;
}
#end
#implementation MasterViewController
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Brothers";
MPTBrothers *First = [[MPTBrothers alloc]initWithInfo:#"JP" age:37 height:5];
MPTBrothers *Second = [[MPTBrothers alloc]initWithInfo:#"Matt" age:33 height:6];
MPTBrothers *Third = [[MPTBrothers alloc]initWithInfo:#"Kevin" age:27 height:5];
NSMutableArray *brothersArray = [NSMutableArray arrayWithObjects:First, Second, Third, nil];
for (id brotherObjects in brothersArray) {
NSLog(#"%#", brotherObjects);
}
NSLog(#"The array count is %lu",brothersArray.count);
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender
{
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
MPTBrothers *brotherCell = [self.brothersArray objectAtIndex:indexPath.row];
cell.textLabel.text = brotherCell.name;
NSLog(#"BrotherCell Name = %#", brotherCell.name);
// NSDate *object = _objects[indexPath.row];
// cell.textLabel.text = [object description];
return cell;
}
Here is my MPTBrothers.m
#import "MPTBrothers.h"
#implementation MPTBrothers
-(id)initWithInfo:(NSString *)name age:(int)age height:(int)height {
if (self = [self init])
_name = name;
_age = age;
_height = height;
return self;
}
Related
I am trying to store data into NSArray using a button and then retrieve it to be displayed in a table. However, the table remains empty after the button has been pushed. I think the problem might have to do with how the Car object is being added to the array and then stored in NSData.
CarTableViewController.h
#import <UIKit/UIKit.h>
#import "CarDetailViewController.h"
#import "Car.h"
#interface CarListTableViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>
#property Car *selectedCar;
#property NSMutableArray *listOfCars;
#property (strong, nonatomic) IBOutlet UITableView *carTableView;
#end
CarTableViewController.m
#import "CarListTableViewController.h"
#import "CarEntryViewController.h"
#implementation CarListTableViewController
#synthesize selectedCar, listOfCars, carTableView;
- (void)viewDidLoad {
[super viewDidLoad];
carTableView.delegate = self;
carTableView.dataSource = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#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 listOfCars.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"carCell" forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"carCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.numberOfLines = 0;
}
Car *tempCar =[listOfCars objectAtIndex:indexPath.row];
cell.textLabel.text =tempCar.make;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:true];
selectedCar = [listOfCars objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"viewDetailsSegue" sender:nil];
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
CarDetailViewController* vc = [segue destinationViewController];
vc.carObject = selectedCar;
}
- (NSArray*) retrieveDataFromNSUserDefaults {
NSMutableArray *objectArray = [NSMutableArray new];
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:#"savedArray"];
if (dataRepresentingSavedArray != nil) {
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
objectArray = [[NSMutableArray alloc]
initWithArray:oldSavedArray];
else
objectArray = [[NSMutableArray alloc] init];
}
return objectArray;
}
- (void)storeDataInNSUserDefaults:(Car *)carToStore {
NSMutableArray *objectArray = [NSMutableArray arrayWithArray:[self retrieveDataFromNSUserDefaults]];
[objectArray addObject:carToStore];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:objectArray] forKey:#"savedArray"];
}
#end
your code looks fine to me but I think you are not calling method to add data [self storeDataInNSUserDefaults:car] anywhere.
I'm using parse.com. I'm trying to display comments but in order to get the comments I have to get the PFObject from my DetailViewController but it doesn't return the PFObject to CommentsViewController
EDIT
here is all the code. I'm new to objective c so I'm probably doing something stupid
CommentsView Controller
#import "CommentsViewController.h"
#import "DetailViewController.h"
#import "CommentsCell.h"
#interface CommentsViewController (){
NSArray *commentsArray;
id commentInstance;
}
#end
#implementation CommentsViewController
- (id)init {
if (self = [super init]) {
[self performSelector:#selector(commentsQuery)];
}
return self;
}
- (void)commentsQuery {
commentInstance = [[DetailViewController alloc] init];
PFObject *tempObj = [commentInstance placeObject];
PFQuery *query1 = [PFQuery queryWithClassName:#"activity"];
[query1 whereKey:#"type" equalTo:#"comment"];
[query1 whereKey:#"place" equalTo:[NSString stringWithFormat:#"%#", [tempObj objectId]]];
NSLog(#"%#", tempObj);
[query1 orderByDescending:#"createdAt"];
[query1 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error){
commentsArray = [[NSArray alloc]initWithArray:objects];
NSLog(#"%lu", (unsigned long)[commentsArray count]);
}
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
static NSString *CellIdentifier = #"Cell";
CommentsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[CommentsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
PFObject *placeObj = [commentInstance placeObject];
cell.username.text = #"test";
return cell;
}
#end
DetailsViewCOntroller
#import "DetailViewController.h"
#import "CommentsViewController.h"
#interface DetailViewController (){
CommentsViewController *test;
}
#end
#implementation DetailViewController
#synthesize place;
#synthesize userPhoto, message, username, checkCount, photo, scroller, commentsTableView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
test = [[CommentsViewController alloc] init];
self.commentsTableView.delegate = test;
self.commentsTableView.dataSource = test;
//Adjust the message label box height
CGSize textSize = [[place objectForKey:#"message"] sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:CGSizeMake(201, CGFLOAT_MAX) lineBreakMode: NSLineBreakByWordWrapping];
userPhoto.file = [place objectForKey:#"thumbnail"];
[userPhoto loadInBackground];
username.text = [place objectForKey:#"username"];
message.text = [place objectForKey:#"message"];
checkCount.text = [NSString stringWithFormat:#"%#", [place objectForKey:#"checkMarkCount"]];
[message sizeToFit];
if ([place objectForKey:#"photo"] != Nil){
photo.file = [place objectForKey:#"photo"];
[photo loadInBackground];
//[photo sizeToFit];
photo.frame = CGRectMake(6, textSize.height + 50, photo.frame.size.width, photo.frame.size.height);
float sizeOfContent = 0;
UIView *lLast = [scroller.subviews lastObject];
NSInteger wd = lLast.frame.origin.y;
NSInteger ht = lLast.frame.size.height;
NSLog(#"%#", lLast);
sizeOfContent = wd+ht;
scroller.contentSize = CGSizeMake(scroller.frame.size.width, sizeOfContent+100);
}
else{
float sizeOfContent = 0;
UIView *lLast = [scroller.subviews lastObject];
NSInteger wd = lLast.frame.origin.y;
NSInteger ht = lLast.frame.size.height;
NSLog(#"%#", lLast);
sizeOfContent = wd+ht;
scroller.contentSize = CGSizeMake(scroller.frame.size.width, sizeOfContent+100);
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)checkMarkButton:(UIButton *)sender {
}
- (PFObject *)placeObject{
return place;
}
#end
I do not see where you allocate place object. You call init and then try retrieving place. It should return nil. Here is your code:
commentInstance = [[DetailViewController alloc] init];
PFObject *tempObj = [commentInstance placeObject];
commentInstance is a new object. There is no init function defined in DetailViewController, hence commentInstance.place is nil and that is returned by placeObject method.
You define place as a property
#property ... place
That gives you a member variable _pace and two member functions, place() and setPlace(place). The object itself is not allocated for you.
Allocate place object in your init function, get rid of placeObject(), replace it with object.place call.
I got rid of all that and in my DetailViewController I added [test placeSet:place] in my viewDidLoad method. Then in CommentsViewController I did...
- (void)placeSet:(PFObject *)object{
place = object;
NSLog(#"place = %#", place);
}
Have added a method and protocol to pass the addItemViewController:didFinishEditingItem method to the main view controller (ChecklistsViewController) after completing a text edit. (The edit command and segue are invoked by pressing a disclosure detail button on the Checklists main page.)
Problem is that after completing the edit and pressing the "Done" button, no completed text edit gets passed back to the original Checklists page, which means that the original edit was was not passed over. I have had no compiling warning messages.
Can you tell me what's wrong and why no completed edit is getting passed back to Checklists? Thanks in advance.
AddItemViewController.h
import
#class AddItemViewController;
#class ChecklistItem;
#protocol AddItemViewControllerDelegate <NSObject>
- (void)addItemViewControllerDidCancel:(AddItemViewController *)controller;
- (void)addItemViewController:(AddItemViewController *)controller didFinishAddingItem:(ChecklistItem *)item;
- (void)addItemViewController:(AddItemViewController *)controller didFinishEditingItem:(ChecklistItem *)item;
#end
#interface AddItemViewController : UITableViewController <UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UITextField *textField;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *doneBarButton;
#property (nonatomic, weak) id <AddItemViewControllerDelegate> delegate;
#property (nonatomic, strong) ChecklistItem *itemToEdit;
- (IBAction)cancel;
- (IBAction)done;
#end
AddItemViewController.m
#import "AddItemViewController.h"
#import "ChecklistItem.h"
#interface AddItemViewController ()
#end
#implementation AddItemViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
if(self.itemToEdit != nil) {
self.title = #"Edit Item";
self.textField.text = self.itemToEdit.text;
self.doneBarButton.enabled = YES;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (IBAction)cancel
{
[self.delegate addItemViewControllerDidCancel:self];
}
- (IBAction)done
{
if(self.itemToEdit == nil) {
ChecklistItem *item = [[ChecklistItem alloc] init];
item.text = self.textField.text;
item.checked = NO;
[self.delegate addItemViewController:self didFinishAddingItem:item];
} else {
self.itemToEdit.text = self.textField.text;
[self.delegate addItemViewController:self didFinishEditingItem:self.itemToEdit];
}
}
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
return nil;
}
- (void)viewDidUnload {
[self setTextField:nil];
[self setDoneBarButton:nil];
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.textField becomeFirstResponder];
}
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newText = [theTextField.text stringByReplacingCharactersInRange:range withString:string];
self.doneBarButton.enabled = ([newText length] > 0);
return YES;
}
#end
ChecklistsViewController.h
#import <UIKit/UIKit.h>
#import "AddItemViewController.h"
#interface ChecklistsViewController : UITableViewController <AddItemViewControllerDelegate>
#end
ChecklistsViewController.m
#import "ChecklistsViewController.h"
#import "ChecklistItem.h"
#interface ChecklistsViewController ()
#end
#implementation ChecklistsViewController {
NSMutableArray *items;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
items = [[NSMutableArray alloc] initWithCapacity:20];
ChecklistItem *item;
item = [[ChecklistItem alloc]init];
item.text = #"Walk the dog";
item.checked = NO;
[items addObject:item];
item = [[ChecklistItem alloc]init];
item.text = #"Brush my teeth";
item.checked = YES;
[items addObject:item];
item = [[ChecklistItem alloc]init];
item.text = #"Learn iOS development";
item.checked = YES;
[items addObject:item];
item = [[ChecklistItem alloc]init];
item.text = #"Soccer practice";
item.checked = NO;
[items addObject:item];
item = [[ChecklistItem alloc]init];
item.text = #"Eat ice cream";
item.checked = YES;
[items addObject:item];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [items count];
}
- (void)configureCheckmarkForCell:(UITableViewCell *)cell withChecklistItem:(ChecklistItem *)item
{
UILabel *label = (UILabel *)[cell viewWithTag:1001];
if(item.checked) {
label.text =#"√";
} else {
label.text = #"";
}
}
- (void)configureTextForCell:(UITableViewCell *)cell withChecklistItem:(ChecklistItem *)item
{
UILabel *label = (UILabel *)[cell viewWithTag:1000];
label.text = item.text;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ChecklistItem"];
ChecklistItem *item = [items objectAtIndex:indexPath.row];
[self configureTextForCell:cell withChecklistItem:item];
[self configureCheckmarkForCell:cell withChecklistItem:item];
return cell;
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
ChecklistItem *item = [items objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"EditItem" sender:item];
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
ChecklistItem *item = [items objectAtIndex:indexPath.row];
[item toggleChecked];
[self configureCheckmarkForCell:cell withChecklistItem:item];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[items removeObjectAtIndex:indexPath.row];
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (void)addItemViewControllerDidCancel:(AddItemViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)addItemViewController:(AddItemViewController *)controller didFinishAddingItem:(ChecklistItem *)item
{
int newRowIndex = [items count];
[items addObject:item];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:0];
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)addItemViewController:(AddItemViewController *)controller didFinishEditingItem:(ChecklistItem *)item
{
int index = [items indexOfObject:item];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self configureCheckmarkForCell:cell withChecklistItem:item];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"AddItem"]) {
UINavigationController *navigationController = segue.destinationViewController;
AddItemViewController *controller = (AddItemViewController *)navigationController.topViewController;
controller.delegate = self;
} else if ([segue.identifier isEqualToString:#"EditItem"]) {
UINavigationController *navigationController = segue.destinationViewController;
AddItemViewController *controller = (AddItemViewController *)navigationController.topViewController;
controller.delegate = self;
controller.itemToEdit = sender;
}
}
#end
I'm using SudzC for an iPhone app. I'm succesfully calling my ASP.Net webservice and pulling the needed data into an NSMutable array called tableData. I have a tableView that should display the contents of tableData; however this is not working. I've looked for hours at this problem. I'm very new to the Objective C world so I'm thinking it's a small oversight on my part. I've linked my TableView to the ViewController (delegate/datasource) as well.
Here's is the code I have:
#import "ViewController.h"
#import "DocumentServiceJSONService.h"
#interface ViewController ()
#end
#implementation ViewController
NSMutableArray *tableData;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewWillAppear:(BOOL) animated {
tableData = [[NSMutableArray alloc] init];
DocumentServiceJSONService* service = [[DocumentServiceJSONService alloc] init];
[service GetAllEMSDocumentsXMLAsString: self action:#selector(handleGetAllEMSDocuments:)];
[super viewWillAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) handleGetAllEMSDocuments:(id) result {
if ([result isKindOfClass:[NSError class]]) {
//if an error has occurred, handle it
return;
}
if([result isKindOfClass: [SoapFault class]]) {
return;
}
NSString* xmlString = result;
CXMLDocument *xmlDoc = [[CXMLDocument alloc] initWithXMLString:xmlString options:0 error:nil];
NSArray *nodes = NULL;
nodes = [xmlDoc nodesForXPath:#"//EMSDocuments" error:nil];
for (CXMLElement *node in nodes) {
NSMutableDictionary *item = [[NSMutableDictionary alloc] init];
int counter;
for (counter = 0; counter < [node childCount]; counter++) {
[item setObject:[[node childAtIndex:counter] stringValue] forKey:[[node childAtIndex:counter] name]];
}
//[item setObject:[[node attributeForName:#"DisplayName"] stringValue] forKey:#"DisplayName"];
NSString *displayName = [item objectForKey:#"DisplayName"];
[tableData addObject:displayName];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
#end
Any advice is appreciated.
Make sure you have in your .h the delegate and datasource correctly set:
#interface YourViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
And if you are using XIBs for the user interface, that the tableview is connected to the File's Owner as datasource and delegate.
--
EDIT:
Creating a Outlet for you tableview:
I am trying to add Search to Todo demo application. I have below code so far with Search working. The issue with below code is that the Pagination doesn't work anymore. There is simlilar question about pagination but when "number of rows in section + 1" returned, the app crashes with [__NSArrayM objectAtIndex:] error. How do I get the Pagination working?
// MyTableController.h
#import <Parse/Parse.h>
#interface MyTableController : PFQueryTableViewController
#end
// MyTableController.m
#import "MyTableController.h"
#interface MyTableController() <UISearchDisplayDelegate> {
}
#property (nonatomic, strong) UISearchBar *searchBar;
#property (nonatomic, strong) UISearchDisplayController *searchController;
#property (nonatomic, strong) NSMutableArray *searchResults;
#end
#implementation MyTableController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
self.className = #"Todo";
self.keyToDisplay = #"text";
self.pullToRefreshEnabled = YES;
self.paginationEnabled = YES;
self.objectsPerPage = 5;
}
return self;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
self.tableView.tableHeaderView = self.searchBar;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar
contentsController:self];
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
self.searchController.delegate = self;
CGPoint offset = CGPointMake(0, self.searchBar.frame.size.height);
self.tableView.contentOffset = offset;
self.searchResults = [NSMutableArray array];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)filterResults:(NSString *)searchTerm {
[self.searchResults removeAllObjects];
PFQuery *query = [PFQuery queryWithClassName: self.className];
[query whereKey:#"text" containsString:searchTerm];
NSArray *results = [query findObjects];
[self.searchResults addObjectsFromArray:results];
}
- (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 ;
}
}
#pragma mark - Parse
- (void)objectsDidLoad:(NSError *)error {
[super objectsDidLoad:error];
}
- (void)objectsWillLoad {
[super objectsWillLoad];
}
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.className];
if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByAscending:#"priority"];
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:#"text"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Priority: %#", [object objectForKey:#"priority"]];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
#end
In your own implementation of numberOfRowsInSection you must return numberOfRows + 1. But then you must write your code considering you have more cells than query returning. Check out your heightForRowAtIndexPath and others methods: there can be calls to [self.objects objectAtIndex:self.objects.count]. I mean, if indexPath.row == self.objects.count, its a "Load More" cell.
If you overriding willSelectRowAtIndexPath or didSelectRowAtIndexPath, you must do this in the top of method
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
or add this (previous case is prefered)
if (indexPath.row == self.objects.count)
{
[self loadNextPage];
}
Customization of Load More cell placed in -(PFTableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:(NSIndexPath *)indexPath
And im using
-(PFTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath
instead of
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: