UITableView don't react on a tap - objective-c

I have a fully working grouped tableview. But when i just tap on a cell - nothing happens. willSelectRowAtIndexPath is not even being called. All outlets are set correctly, userInteractions are enabled, tableView is the only view on a page. Googling for hours made no success. Everyone has a selection feature from the begining and someone even tries to ged rid of it. Help, please.
Code (bad one, i know):
//
// VKFriendsPage.m
// vKontakte
//
// Created by ASPCartman on 3/29/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "VKFriendsPage.h"
#import "UIImage+Resize.h"
#import "VKProfilePage.h"
#implementation VKFriendsPage
#synthesize friends,onlineFriends,VKId,connection,avatarCache;
-(void) didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
NSLog(#" Memary Wornenk!!! OLOLOLOLOL!");
}
-(void)viewWillAppear:(BOOL)animated
{
table.backgroundColor=[UIColor clearColor];
if ([connection.myVkontakteID isEqual:VKId]) {
friends=[connection.myVKProfile friendsAll];
onlineFriends=[connection.myVKProfile friendsOnline];
}
self.avatarCache = [NSMutableDictionary dictionaryWithCapacity:2];
queue = [NSOperationQueue new];
table.allowsSelection=YES;
}
#pragma mark Table Data Source Protocol Implementation
//Количество строк в секции
//0ая - Ребята онлайн
//1ая - Все
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
if (section==0) {
return [onlineFriends count];
}else if (section==1) {
return [friends count];
}else {
return 0;
}
}
//Создание клеток
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Инит клетки
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"FriendCell"];
//Выбор секции
NSArray *currentMan;
if (indexPath.section==0) {
currentMan=[onlineFriends objectAtIndex:indexPath.row];
}else if (indexPath.section==1)
{
currentMan=[friends objectAtIndex:indexPath.row];
}else {
currentMan=nil;
}
cell.selectionStyle=UITableViewCellSelectionStyleBlue;
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text=[currentMan objectAtIndex:1];
cell.detailTextLabel.text=#"TODO: Статусы...";
if ([avatarCache objectForKey:[currentMan objectAtIndex:2]]==nil) {
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:indexPath,#"Path",[currentMan objectAtIndex:2],#"URLString",nil];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:#selector(fetchAvatar:)
object:dic];
[cell.imageView setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"profileIco" ofType:#"jpg"]]];
[queue addOperation:operation];
[operation autorelease];
}else {
[cell.imageView setImage:[avatarCache objectForKey:[currentMan objectAtIndex:2]]];
}
return [cell autorelease];
}
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
VKProfilePage *profilePage=[[VKProfilePage alloc] init];
profilePage.title=[tableView cellForRowAtIndexPath:indexPath].textLabel.text;
profilePage.connection=connection;
NSString *VKID;
if (indexPath.section==0) {
VKID=[[onlineFriends objectAtIndex:indexPath.row] objectAtIndex:0];
}else if (indexPath.section==1) {
VKID=[[friends objectAtIndex:indexPath.row] objectAtIndex:0];
}
profilePage.profile=[connection getProfileOf:VKID];
[self.navigationController pushViewController:profilePage animated:YES];
[profilePage release];
}
-(void)fetchAvatar:(NSDictionary *)dic
{
NSData *imageData=[NSData dataWithContentsOfURL:[NSURL URLWithString:[dic objectForKey:#"URLString"]]];
UIImage *image=[UIImage imageWithData:imageData];
UIImage *resizedImage = [image thumbnailImage:70 transparentBorder:0 cornerRadius:5 interpolationQuality:kCGInterpolationHigh];
[avatarCache setObject:resizedImage forKey:[dic objectForKey:#"URLString"]];
[self performSelectorOnMainThread:#selector(updateRow:) withObject:[dic objectForKey:#"Path"] waitUntilDone:NO];
}
-(void)updateRow:(NSIndexPath *) ip
{
[table reloadRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationNone];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
{
return NO;
};
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section==0) {
return #"Online";
}else {
return #"Offline";
}
}
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
return nil;
};
#end

Did you implement something like this in your UITableView delegate?
- (BOOL)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
Sorry, wrong assumption and a compiler warning ignored...
This is not the solution.

I did some experiments and found the property isUserInteractionEnabled on the UITableView View ancestor. If set to NO, the cell selection is disabled (as is any other interaction). In this case it is impossible to move the views cells up and down.

Related

Objective-C : Always display 3 rows in UITableView

After scrolling i want my TableView to display like this :
not like this :
and i have set my rowHeight = tableViewHeight / 3:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return CGRectGetHeight(self.tableView.frame)/3;
}
There are a couple things you need for this. Firstly, you need to detect when the table view has stopped scrolling:
How to know exactly when a UIScrollView's scrolling has stopped?
Next, you need to set the scroll view position:
How can I set the scrolling position of an UIScrollView?
The position you're going to want to set it might be the tableview contentOffset - (contentOffset % rowHeight) to move it up to show the row partially shown at the top.
Follow this steps:
In .h , declare
NSMutableArray *arrayForBool;
NSMutableArray *arrPastOrder;
In .m ,
- (void)viewDidLoad {
arrPastOrder=[[NSMutableArray alloc] init];
int range=1+arc4random()%10;
for(int i=0;i<range;i++)
{
NSMutableArray *arrinside=[[NSMutableArray alloc] init];
for(int j=0;j<3;j++)
{
if(j==0)
[arrinside addObject:[NSString stringWithFormat:#"Some Header %i",i]];
else
[arrinside addObject:[NSString stringWithFormat:#"Subindex %i",j]];
}
[arrPastOrder addObject:arrinside];
}
arrayForBool=[[NSMutableArray alloc]init];
for (int i=0; i<[arrPastOrder count]; i++)
{
[arrayForBool addObject:[NSNumber numberWithBool:YES]];
}
}
#pragma mark -
#pragma mark TableView DataSource and Delegate Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([[arrayForBool objectAtIndex:section] boolValue])
{
return [[arrPastOrder objectAtIndex:section] count]-1;
}
else
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *cellid=#"hello";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellid];
if (cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellid];
}
BOOL manyCells = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
/********** If the section supposed to be closed *******************/
if(!manyCells)
{
cell.backgroundColor=[UIColor clearColor];
NSLog(#"cellForRowAtIndexPath---if");
cell.textLabel.text=#"";
}
/********** If the section supposed to be Opened *******************/
else
{
//cell.textLabel.text=[NSString stringWithFormat:#"%# %ld",[sectionTitleArray objectAtIndex:indexPath.section],indexPath.row+1];
// ic_keyboard_arrow_up_48pt_2x ic_keyboard_arrow_down_48pt_2x.png
cell.textLabel.text=[NSString stringWithFormat:#"%#",[[arrPastOrder objectAtIndex:indexPath.section] objectAtIndex:indexPath.row+1]];
}
cell.textLabel.textColor=[UIColor blackColor];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrPastOrder count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%li--%li",(long)indexPath.section, (long)indexPath.row);
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[arrayForBool objectAtIndex:indexPath.section] boolValue]) {
return 40;
}
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 100;
}
#pragma mark - Creating View for TableView Section
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *sectionView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 540,100)];
sectionView.backgroundColor=[UIColor whiteColor];
sectionView.tag=section;
UILabel *viewLabel=[[UILabel alloc]initWithFrame:CGRectMake(10, 30, 530, 40)];
viewLabel.backgroundColor=[UIColor whiteColor];
viewLabel.textColor=[UIColor blackColor];
viewLabel.font=[UIFont boldSystemFontOfSize:20];
viewLabel.text=[NSString stringWithFormat:#"%#",[[arrPastOrder objectAtIndex:section] objectAtIndex:0]];
[sectionView addSubview:viewLabel];
/********** Add UITapGestureRecognizer to SectionView **************/
UITapGestureRecognizer *headerTapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(sectionHeaderTapped:)];
[sectionView addGestureRecognizer:headerTapped];
return sectionView;
}
#pragma mark - Table header gesture tapped
- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag];
//Get which section is open, from here Set the value of arrafool. and expand collapse. Normally whole table is expanded.
}
Just run it. You will get the same structure. happy Coding !!

Objective-C syntax error - unexpected "#" / unable to fix problems

enter code here[youtube picture of the same code][1]I keep getting an error with my code where it says
"unexpected "#" in program and also missing "#end"
If you look at the code below the #end is there but however much I retype it the answer is the same "missing #end"
Here is the full code
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController ()
#end
#implementation MasterViewController
-(NSMutableArray *) objects
{
if (!_objects){
_objects =[[NSMutableArray alloc]init];
}
return _objects;
}
-(NSMutableArray *) results
{
if (!_results) {
_results =[[NSMutableArray alloc]init];
}
return _results;
}
-(void)viewDidLoad
{
[super viewDidLoad];
[self.objects addObject:#"Tabebuia yellow"];
[self.objects addObject:#"Prunus armeniaca"];
[self.objects addObject:#"Tabebuia rosea"];
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) searchThroughData
{
self.results= nil;
NSPredicate * resultsPredicate = [NSPredicate predicateWithFormat:#"SELF contains [search]%#", self.searchBar.text];
self. results = [[ self.objects filteredArrayUsingPredicate:resultsPredicate]mutableCopy];
}
-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self searchThroughData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.tableView)
{
return self.objects.count;
}else{
[self searchThroughData];
return self.results.count;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if (tableView == self.tableView){
cell.textLabel.text = self.objects[indexPath.row];
} else {
cell.textLabel.text = self.results[indexPath.row];
}
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (self.searchController.isActive)
{
[self performSegueWithIdentifier:#"Showdetail" sender:self];
}
-(void) PrepareForSegue:(UIStoryboardSegue *) segue sender:(id) sender
if ([[ segue identifier] isEqualToString:#"ShowDetail"]) {
NSString *object = nil;
NSIndexPath *Indexpath = nil;
if (self.UISearchController.isActive)
{UISearchController
Indexpath = [[ self.searchController searchResultsTableView]indexPathForSelectedRow];
object = self.results [Indexpath.row];
}else{
Indexpath = [self.tableView indexPathForSelectedRow];
object = [[self.objects [Indexpath.row];
[segue destinationViewController] setDetailLabelContents:object];
}}
#end
You have no closing } at the end of the prepareForSegue:sender: method. Formatting and indenting properly makes this clear.
You have code just floating outside of a method (the lines before the tableView:didSelectRowAtIndexPath: method.
There needs to be a proper pairing of { and } and code needs to be inside methods or functions.

Parse search table not returning correct results

I am using parse as back-end for my app. I have found a few different methods to implement searchbar feature using a Parse tableview. This idea I found from Parse archives shows all objects on initial view and refresh, but when I search it does not return the correct results. If I type one letter "a" it returns some objects containing "a" but if I type more letters or and actual word that I know should be found it returns a blank table. It is also giving a warning when searching: A long-running Parse operation is being executed on the main thread. I have been working and researching this for a few weeks and can't get past this point. See code for implementation file.
#import "RecipeBookViewController.h"
#import "SearchedResultCell.h"
#import "RecipeDetailViewController.h"
#import "HotelViewController.h"
#import "Recipe.h"
static NSString *const NothingFoundCellIdentifier = #"NothingFoundCell";
#interface RecipeBookViewController ()
#end
#implementation RecipeBookViewController {
}
#synthesize searchedBar;
#synthesize searchResults;
#synthesize recipesTable;
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Recipe";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"name";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = NO;
// The number of objects to show per page
//self.objectsPerPage = 10;
}
return self;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - UIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UINib *cellNib = [UINib nibWithNibName:NothingFoundCellIdentifier bundle:nil];
[self.tableView registerNib:cellNib forCellReuseIdentifier:NothingFoundCellIdentifier];
[self.searchedBar becomeFirstResponder];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(refreshTable:)
name:#"refreshTable"
object:nil];
}
- (void)refreshTable:(NSNotification *) notification
{
// Reload the recipes
[self loadObjects];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"refreshTable" object:nil];
}
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchResults removeAllObjects];
[self.searchedBar resignFirstResponder];
searchResults = [NSMutableArray arrayWithCapacity:10];
//#warning Put your ClassName here
PFQuery *query = [PFQuery queryWithClassName:#"Recipe"];
//#warning put key that you want to search here
[query whereKey:#"name" containsString:searchedBar.text];
NSArray *results = [query findObjects];
[searchResults addObjectsFromArray:results];
//#warning put your key here
[query orderByAscending:#"name"];
//[self queryForTable];
[self loadObjects];
}
#pragma mark - PFQueryTableViewController
- (void)objectsWillLoad {
[super objectsWillLoad];
// This method is called before a PFQuery is fired to get more objects
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
#pragma mark - Query
- (PFQuery *)queryForTable
{
PFQuery *query;
if (self.searchResults == 0) {
query = [PFQuery queryWithClassName:self.parseClassName];
} else {
query = [PFQuery queryWithClassName:self.parseClassName];
NSString *searchThis = [searchedBar.text lowercaseString];
//#warning key you wanted to search here
[query whereKeyExists:#"name"];
[query whereKey:#"name" containsString:searchThis];
}
[query orderByAscending:#"name"];
// If Pull To Refresh is enabled, query against the network by default.
if (self.pullToRefreshEnabled) {
query.cachePolicy = kPFCachePolicyNetworkOnly;
}
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
return query;
}
/*
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
if (searchResults == nil) {
return 0;
} else if ([searchResults count] == 0) {
return 1;
} else {
return [self.objects count];
}
}
*/
// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the first key in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"recipeBoxImage2.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"prepTime"];
static NSString *LoadMoreCellIdentifier = #"LoadMoreCell";
UITableViewCell *loadcell = [self.tableView dequeueReusableCellWithIdentifier:LoadMoreCellIdentifier];
if (!cell) {
loadcell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:LoadMoreCellIdentifier];
}
return cell;
}
- (void)configureSearchResult:(SearchedResultCell *)cell atIndexPath: (NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
SearchedResultCell *searchcell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (searchcell == nil) {
searchcell = [[SearchedResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"recipeBoxImage2.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"prepTime"];
}
// Set CellForRowAtIndexPath
- (UITableViewCell *)searchtableView:(UITableView *)searchtableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *CellIdentifier = #"SearchResultCell";
//Custom Cell
SearchedResultCell *cell = [searchtableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[SearchedResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([searchResults count] == 0) {
//cell.mainTitle.text = #"Nothing Found";
return [self.tableView dequeueReusableCellWithIdentifier:NothingFoundCellIdentifier];
} else {
//#warning put your ClassName here
PFObject *object = [PFObject objectWithClassName:#"Recipe"];
object = [searchResults objectAtIndex:indexPath.row];
[self configureSearchResult:cell atIndexPath:indexPath object:object];
//[self configureSearchResult:cell atIndexPath:indexPath object:object];
return cell;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:(NSIndexPath *)indexPath {
static NSString *LoadMoreCellIdentifier = #"LoadMoreCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:LoadMoreCellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:LoadMoreCellIdentifier];
}
return cell;
}
//// Set TableView Height for Load Next Page
//- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath {
// if([self.objects count] == indexPath.row) {
// // Load More Cell Height
// return 60.0;
// } else {
// return 80.0;
// }
//}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[searchedBar resignFirstResponder];
if ([self.objects count] == indexPath.row) {
[self loadNextPage];
} else {
PFObject *photo = [self.objects objectAtIndex:indexPath.row];
NSLog(#"%#", photo);
// Do something you want after selected the cell
}
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.searchedBar resignFirstResponder];
}
//- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
//{
// // Remove the row from data model
// PFObject *object = [self.objects objectAtIndex:indexPath.row];
// [object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// [self refreshTable:nil];
// }];
//}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Recipe *recipe = [[Recipe alloc] init];
recipe.name = [object objectForKey:#"name"];
recipe.imageFile = [object objectForKey:#"imageFile"];
recipe.prepTime = [object objectForKey:#"prepTime"];
recipe.ingredients = [object objectForKey:#"ingredients"];
recipe.instructions = [object objectForKey:#"instructions"];
recipe.servings = [object objectForKey:#"servings"];
recipe.hotelSite = [object objectForKey:#"hotelSite"];
recipe.recipeType = [object objectForKey:#"recipeType"];
destViewController.recipe = recipe;
}
}
#end
found this - hope it helps others - credit to Bizzi-Body
https://github.com/Bizzi-Body/ParseTutorial-Part-2
//
// GourmetChefViewController.m
//
// Created by RedMac on 3/19/15.
//
#import "RecipeBookViewController.h"
#interface RecipeBookViewController ()
{
NSMutableArray *totalStrings;
NSMutableArray *filteredStrings;
BOOL isFiltered;
}
#end
#implementation RecipeBookViewController
#pragma mark -
#pragma mark UIViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
self.mySearchBar.delegate =self;
self.myTableView.delegate = self;
self.myTableView.dataSource=self;
[self retrieveFromParse];
}
- (void) retrieveFromParse {
PFQuery *retrieveRecipes = [PFQuery queryWithClassName:#"Recipe"];
[retrieveRecipes whereKeyExists:#"name"];
[retrieveRecipes findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"%#", objects);
totalStrings = [[NSMutableArray alloc] initWithArray:objects];
}
[self.myTableView reloadData];
}];
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *) searchText{
if (searchText.length ==0){
isFiltered =NO;}
else{
isFiltered =YES;
filteredStrings=[[NSMutableArray alloc]init];
for(PFObject *element in totalStrings) {
NSString * str = [element objectForKey:#"name"];
NSLog(#"%#", NSStringFromClass([element class])); // you thought that totalStrings
// contained NSString objects,
// but it contains PFObjects.
NSRange stringRange =[str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (stringRange.location !=NSNotFound) {
// you need to add the PFObject back to make your cellForRowAtIndexPath: method
// work.
[filteredStrings addObject:element]; // used to be :str
}
}
}
[self.myTableView reloadData];
}
//table view datasource and delegate method.....
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section
{
if (isFiltered){
return [filteredStrings count];
}return [totalStrings count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"RecipeCell";
UITableViewCell *cell= [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (!cell){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(!isFiltered){
PFObject *tempObject =[totalStrings objectAtIndex: indexPath.row];
cell.textLabel.text = [tempObject objectForKey:#"name"];
}
else
{
PFObject *tempObject2 =[filteredStrings objectAtIndex: indexPath.row];
cell.textLabel.text =[tempObject2 objectForKey:#"name"];
}
return cell;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

How to add Pagination to Tableview on Search results?

The following lines of code shown below are my current tableview settings. What i would like to achieve is what's seen on the image below.
1) if count is 4 when user scrolls Down show a Activity Indicator and Make a request using the next value shown on the JSON Below.
2) Reload the Table
3) Show No more results if count is empty.
Note: I am new on Objective-C so I will appreciate your guidance on this subject since all searches I have done were not successful on what I am looking to achieve since all of them are based on a table already loaded and not based on a Search Result.
As shown on the Image Below is a reference what i want to achieve.
JSON RESPONSE FROM SEARCH
{
"count": 4,
"next": "http://api.domain.com/user-search/?page=2&subject=culture",
"previous": null,
"results": [
{
"name": "Guillermo Davila",
"nick": "guillermo",
"avatar_s": "https://pbs.twimg.com/profile_images/2213685686/image.jpg",
"user_rate": "$10/h",
"id": 3,
"subjects": "Culture and 1 other subject",
"bio": "I'm a nice person"
},
{
"name": "Frank Smith",
"nick": "fsmith",
"avatar_s": "https://pbs.twimg.com/profile_images/2444486/image.jpg",
"user_rate": "$14/h",
"id": 3,
"subjects": "Culture and 1 other subject",
"bio": "I'm a nice person 2"
}
]
}
And here is my UserTableviewController.h
//
// UserTableViewController.m
// mobile-app
//
// Created by eddwinpaz on 5/18/14.
// Copyright (c) 2014 eddwinpaz. All rights reserved.
//
#import "UserTableViewController.h"
#import "CustomTableCell.h"
#import "UserDetailViewController.h"
#import "AFNetworking.h"
#import "MBProgressHUD.h"
#import "SimpleAudioPlayer.h"
#interface UserTableViewController ()
#end
#implementation UserTableViewController
{
// JSON Request
NSMutableArray *myObject;
// A Dictionary Object
NSDictionary *dictionary;
NSString *name;
NSString *subject;
NSString *avatar;
NSString *rate;
NSString *bio;
NSString *nick;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//[self fetch_tutors]; // Get tutors Ordered By Karma DESC
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (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 0;
} */
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return myObject.count; // This is old 100% working code
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
dictionary = [myObject objectAtIndex:indexPath.row];
cell.labelName.text = [dictionary objectForKey:#"name"];
cell.labelBio.text = [dictionary objectForKey:#"bio"];
cell.labelSubjects.text = [dictionary objectForKey:#"subject"];
cell.imageAvatar.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[dictionary objectForKey:#"avatar"]]]];
cell.imageAvatar.clipsToBounds = YES;
cell.imageAvatar.layer.cornerRadius = cell.imageAvatar.frame.size.width / 2;
cell.labelRate.text = [dictionary objectForKey:#"rate"];
cell.labelRate.layer.cornerRadius = 5;
[SimpleAudioPlayer playFile:#"upvote.wav"];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showUserDetail"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UserDetailViewController *destViewController = segue.destinationViewController;
NSDictionary *dict = [myObject objectAtIndex:indexPath.row];
destViewController.http_nick = [dict valueForKey:#"nick"];
destViewController.labelName = [dict valueForKey:#"name"];
NSLog(#" Username Sent--->%#", [dict valueForKey:#"nick"]);
NSLog(#" name Sent--->%#", [dict valueForKey:#"name"]);
}
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
NSString *searchTerm = searchBar.text;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = #"Searching Tutors";
[hud show:YES];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *url = [NSString stringWithFormat:#"http://api.domain.com/user-search/?subject=%#",searchTerm];
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
[hud hide:YES];
int count_total = [[responseObject objectForKey:#"count"] intValue];
if (count_total == 0) {
[myObject removeAllObjects];
NSLog(#"Count is --->0");
}
else {
myObject = [[NSMutableArray alloc] init];
name = #"name";
subject = #"subject";
avatar = #"avatar";
rate = #"rate";
bio = #"bio";
nick = #"nick";
for (NSDictionary *dataDict in [responseObject objectForKey:#"results"])
{
NSString *name_data = [dataDict objectForKey:#"name"];
NSString *subject_data = [dataDict objectForKey:#"subjects"];
NSString *avatar_data = [dataDict objectForKey:#"avatar_s"];
NSString *rate_data = [dataDict objectForKey:#"user_rate"];
NSString *bio_data = [dataDict objectForKey:#"bio"];
NSString *nick_data = [dataDict objectForKey:#"nick"];
NSLog(#"name: %#", name_data);
NSLog(#"subjects: %#",subject_data);
NSLog(#"avatar_s: %#", avatar_data);
NSLog(#"user_rate: %#",rate_data);
NSLog(#"bio: %#",bio_data);
NSLog(#"nick: %#",nick_data);
dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
name_data,name,
subject_data,subject,
avatar_data,avatar,
rate_data,rate,
bio_data, bio,
nick_data, nick, nil];
[myObject addObject:dictionary];
}
}
[self.searchBar endEditing:YES];
[self.searchBar setShowsCancelButton:NO animated:YES];
[self.searchBar sizeToFit];
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
[hud hide:YES];
}];
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
[searchBar sizeToFit];
[searchBar setShowsCancelButton:YES animated:YES];
return YES;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[self.searchBar endEditing:YES];
[searchBar setShowsCancelButton:NO animated:YES];
self.searchBar.text = nil;
}
/*
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"userDetailView"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UserDetailViewController *destViewController = segue.destinationViewController;
destViewController.labelName = [myObject objectAtIndex:indexPath.row];
}
} */
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
One way to achieve it is,
Return the numberOfCells as one more than the data array
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return myDataArray +1 ; //myDataArray is the data and One more cell for the last cell (10 out of 46 results cell)
}
In cellForRowAtIndexPath, if your IndexPath.row == myDataArray.count (ie., Last Row) Create a custom cell which looks as in the picture and return the custom cell.
In - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath, If the indexPath corresponds to last cell, then Start Request for page 2, once the results are fetched, update the myDataArray and reload the table.

Parse.com - How to get PFQueryTableViewController , Pagination working with UISearchDisplayController?

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: