Hey together I am using Parse SDK for my App - the interface is build in Storyboard...
I am having a table view which get's his data from Parse, now I want to make it searchable.
I found this post and followed it but not came to a running result! :/
The search results are load but I having problems to display them...
I get the following errors:
... myApp[..] *** Assertion failure in -[UISearchResultsTableView _configureCellForDisplay:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:5471
... myApp[...] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
I tried a lot around but don't come to a result, here is my code - can anybody help:
Sorry for my bad english! ;)
#import "FirstLaunchViewController.h"
#interface FirstLaunchViewController ()
#end
#implementation FirstLaunchViewController
#pragma mark - UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self loadObjects];
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"navbar_background.png"] forBarMetrics:UIBarMetricsDefault];
self.searchResults = [NSMutableArray array];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithClassName:#"teams"];
self = [super initWithCoder:aDecoder];
if (self) {
// The className to query on
self.parseClassName = #"teams";
self.textKey = #"verein";
// The key of the PFObject to display in the label of the default cell style
// self.keyToDisplay = #"text";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = NO;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
self.loadingViewEnabled = NO;
// The number of objects to show per page
self.objectsPerPage = 50;
}
return self;
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait || UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
PFTableViewCell *cell = (PFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"Cell"];
// Configure the cell
UIColor *color = [[UIColor alloc] initWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
cell.detailTextLabel.backgroundColor = color;
cell.textLabel.backgroundColor = color;
cell.backgroundView = [ [UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"cellbackground_n.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];
cell.selectedBackgroundView = [ [UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"cellbackground_down_n.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];
cell.accessoryView = [[ UIImageView alloc ] initWithImage:[UIImage imageNamed:#"cellarrows.png" ]];
if (tableView == self.tableView) {
cell.textLabel.text = [object objectForKey:#"verein"];
} else {
PFUser *obj2 = [self.searchResults objectAtIndex:indexPath.row];
PFQuery *query = [PFQuery queryWithClassName:#"teams"];
PFObject *searchedUser = [query getObjectWithId:obj2.objectId];
NSString *content = [searchedUser objectForKey:#"verein"];
cell.textLabel.text = content;
NSLog(#"Content: %#", content);
}
return cell;
}
-(void)filterResults:(NSString *)searchTerm {
[self.searchResults removeAllObjects];
PFQuery *query = [PFQuery queryWithClassName: self.parseClassName];
[query whereKeyExists:#"verein"]; //this is based on whatever query you are trying to accomplish
[query whereKey:#"verein" containsString:searchTerm];
NSArray *results = [query findObjects];
NSLog(#"%#", results);
NSLog(#"%u", results.count);
[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;
}
}
#end
The issue is that your tableView initially has no reusable cells to dequeue. You need to check whether the cell returned by dequeueReusableCellWithIdentifier: is nil, and create a cell if it is.
PFTableViewCell *cell = (PFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (!cell)
{
cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
// Configure the cell
...
This way, you are guaranteeing that cell has a value, so you can avoid returning nil from this method.
To handle tableView:didSelectRowAtIndexPath: correctly, you'll need to first check which tableView triggered the event, and handle it accordingly. Below is an example of how this could work - you'd need to substitute your own detail view controller.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.tableView) {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
else {
PFUser *user = PFUser *obj2 = [self.searchResults objectAtIndex:indexPath.row];
MyDetailViewController *detailController = [[MyDetailViewController alloc] initWithObject:user];
[self.navigationController pushViewController:datailController animated:YES];
}
}
Related
I am new to iOS. I am making an app in which i am getting data from Parse back-end all are working fine.
I did UISearchbar and it works well. But when a search produces more than 6 results (main table have 6 rows, but I search for another Parse class) , this leads to an error.
2015-06-09 14:10:23.318 Aero store[3238:347073] Terminating app due to uncaught exception 'NSRangeException', reason: '
-[__NSArrayM objectAtIndex:]: index 6 beyond bounds [0 .. 5]'
This is my code:
#import "CategoryTable.h"
#import "GoodsTable.h"
#import "Parse/Parse.h"
#interface CategoryTable ()<UISearchDisplayDelegate, UISearchBarDelegate>
#property (nonatomic, strong) UISearchDisplayController *searchController;
#property (nonatomic, strong) NSMutableArray *searchResults;
#end
#implementation CategoryTable
#synthesize categoryId;
- (void)viewDidLoad {
[super viewDidLoad];
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.goodsSearchBar contentsController:self];
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
self.searchController.delegate = self;
[self.searchDisplayController.searchBar setBackgroundImage:[UIImage imageNamed:#"menu-background"]
forBarPosition:0
barMetrics:UIBarMetricsDefault];
CGPoint offset = CGPointMake(0, self.goodsSearchBar.frame.size.height);
self.tableView.contentOffset = offset;
self.searchResults = [NSMutableArray array];
self.navigationController.navigationBar.barStyle = UIStatusBarStyleLightContent;
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStylePlain target:nil action:nil];
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"] != nil) {
//Город установлен - > категории
NSLog(#"Gorod - %#", [[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"]);
//[self performSegueWithIdentifier:#"showCategory" sender:self];
}
else
{
//Город не установлен -> выбор города
NSLog(#"Gorod - %#", [[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"]);
}
//Установка лого
UIView *headerView = [[UIView alloc] init];
headerView.frame = CGRectMake(0, 0, 151, 20);
UIImageView *logoImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo"]];
logoImage.frame = CGRectMake(0, 0, 151, 20);
logoImage.contentMode = UIViewContentModeScaleAspectFit;
[headerView addSubview:logoImage];
[self.navigationItem setTitleView:headerView];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.parseClassName = #"Category";
self.pullToRefreshEnabled = NO;
self.paginationEnabled = NO;
}
return self;
}
//Слово для поиска
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
searchString = [searchString lowercaseString];
[self filterResults:searchString];
return NO;
}
//Запрос для поиска
-(void)filterResults:(NSString *)searchTerm {
if (searchTerm.length > 1) {
[PFCloud callFunctionInBackground:#"find"
withParameters:#{#"goodsName": searchTerm, #"city":[[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"]}
block:^(NSArray *goodsList, NSError *error) {
if (!error) {
NSLog(#"Найдено: %#",goodsList);
[self.searchResults removeAllObjects];
[self.searchResults addObjectsFromArray:goodsList];
dispatch_async(dispatch_get_main_queue(), ^{
[self.searchController.searchResultsTableView reloadData];
});
}
}];
}
}
//Получени списка категорий
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
[query whereKey:#"cityName" equalTo:[[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"]];
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByAscending:#"createdAt"];
return query;
}
//Количество ячеек для результата поиска
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchDisplayController.searchResultsTableView) {
return self.searchResults.count;
}
else {
return self.objects.count;
}
}
//Обрезка пустых ячеек
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView *sectionFooterView = [[UIView alloc] initWithFrame:
CGRectMake(0, 0, tableView.frame.size.width, 1)];
sectionFooterView.backgroundColor = [UIColor clearColor];
return sectionFooterView;
}
//Отрисовка ячеек категорий
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *identifier = #"categoryCell";
PFTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
if (tableView == self.tableView) {
UILabel *titleLabel = (UILabel*) [cell viewWithTag:200];
titleLabel.text = [object objectForKey:#"title"];
PFFile *thumbnail = [object objectForKey:#"image"];
PFImageView *catImageView = (PFImageView*)[cell viewWithTag:100];
catImageView.image = [UIImage imageNamed:#"placeholder"];
catImageView.file = thumbnail;
[catImageView loadInBackground];
}
else if(tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"test");
PFObject *searchedUser = [self.searchResults objectAtIndex:indexPath.row];
cell.textLabel.text = [[searchedUser objectForKey:#"name"] capitalizedString];
}
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showGoods"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
GoodsTable *goods= segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
categoryId = [object objectForKey:#"title"];
NSLog(#"Category Name = %#", categoryId);
goods.cityName = [[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"];
goods.categoryId = categoryId;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Please help me! I can not solve the problem for several days. :'(
Try
dispatch_async(dispatch_get_main_queue(), ^{
[self.searchResults removeAllObjects];
[self.searchResults addObjectsFromArray:goodsList];
[self.searchController.searchResultsTableView reloadData];
});
to ensure editing your datasource and reloading your tablew view are done in the same dispatch queue.
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'm trying to implement a UISearchBar in a custom UITableViewController and done programmatically (not using IB). I got the search function to work and return the correct fields, but it is displaying the searched cells over the full list cells:
As you can see, the new searched field is scrollable and selectable. Its just not removing the old cells.
here is my .h file:
#interface TestTableViewController : UITableViewController <UISearchBarDelegate, UISearchDisplayDelegate>
#property (strong, nonatomic) NSArray *boundaries;
#end
.m file:
#import "TestTableViewController.h"
#import "Boundary.h"
#interface TestTableViewController ()
#property (strong, nonatomic) UISearchDisplayController *searchController;
#property (strong, nonatomic) NSMutableArray *filteredBoundaries;
#end
#implementation TestTableViewController
-(instancetype) initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
self.filteredBoundaries = [NSMutableArray array];
}
return self;
}
-(void)viewDidLoad {
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:TRUE selector:#selector(caseInsensitiveCompare:)];
NSArray *sortDescriptors = #[sortDescriptor];
self.boundaries = [self.boundaries sortedArrayUsingDescriptors:sortDescriptors];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchBar.delegate = self;
searchBar.placeholder = #"Search Fields";
searchBar.showsCancelButton = TRUE;
self.tableView.tableHeaderView = searchBar;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchController.delegate = self;
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
}
// ------------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark Setup Filter Data Source
-(void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope {
[self.filteredBoundaries removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
self.filteredBoundaries = [NSMutableArray arrayWithArray:[self.boundaries filteredArrayUsingPredicate:predicate]];
}
// ------------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark Table view data source
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchDisplayController.searchResultsTableView) {
return self.filteredBoundaries.count;
}
else {
return self.boundaries.count;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
Boundary *boundary = [self.filteredBoundaries objectAtIndex:indexPath.row];
cell.textLabel.text = boundary.name;
cell.textLabel.textColor = [UIColor blackColor];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
}
else {
Boundary *boundary = [self.boundaries objectAtIndex:indexPath.row];
cell.textLabel.text = boundary.name;
cell.textLabel.textColor = [UIColor blackColor];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
cell.userInteractionEnabled = TRUE;
}
return cell;
}
// ------------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark UISearchDisplayController Delegates
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterContentForSearchText:searchString scope:[[self.searchController.searchBar scopeButtonTitles] objectAtIndex:self.searchController.searchBar.selectedScopeButtonIndex]];
return TRUE;
}
#end
And how I call the table view:
TestTableViewController *tableViewController = [[TestTableViewController alloc] initWithStyle:UITableViewStylePlain];
tableViewController.boundaries = [group.boundaries allObjects];
tableViewController.contentSizeForViewInPopover = POPOVER_SIZE;
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
navController.navigationBar.barStyle = UIBarStyleBlack;
self.myPopoverController = [[UIPopoverController alloc] initWithContentViewController:navController];
self.myPopoverController.delegate = self;
[self.myPopoverController presentPopoverFromRect:button.frame inView:button.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
Any ideas what I might be doing wrong or missing?
The problem is that UISearchDisplayController is using another UITableView rather than the view controller's own. You can verify that by logging tableView in -tableView:cellForRowAtIndexPath:.
You can use a UISearchBar without a UISearchDisplayController, to have more control over search and display logic.
Also, if your app doesn't support any version prior to iOS 8, consider using UISearchController. I haven't tried it but it seems to give you more control. Check a sample UISearchDisplayControllerhas been deprecated in iOS 8.
Try this
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 41.0)];
[self.view addSubview:searchBar];
searchBar.delegate=self;
- (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.
if (isSearching) {
return [filteredContentList count];
}
else {
return [titlearray count];
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (isSearching)
{
cell.nameLabel.text = [filteredContentList objectAtIndex:indexPath.row];
cell.thumbnailImageView.image =[filteredImgArray objectAtIndex:indexPath.row];
}
else
{
cell.thumbnailImageView.image = [imagearray objectAtIndex:indexPath.row];
cell.nameLabel.text = [titlearray objectAtIndex:indexPath.row];
}
return cell;
}
- (void)searchTableList {
NSString *searchString = searchBar.text;
for (int i=0; i<titlearray.count; i++) {
NSString *tempStr=[titlearray objectAtIndex:i];
NSComparisonResult result = [tempStr compare:searchString options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchString length])];
if (result == NSOrderedSame)
{
[filteredContentList addObject:tempStr];
[filteredImgArray addObject:[imagearray objectAtIndex:i]];
}
}
}
#pragma mark - Search Implementation
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
isSearching = YES;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"Text change - %d",isSearching);
//Remove all objects first.
[filteredContentList removeAllObjects];
[filteredImgArray removeAllObjects];
if([searchText length] != 0) {
isSearching = YES;
[self searchTableList];
//tblContentList.hidden=NO;
}
else {
isSearching = NO;
// tblContentList.hidden=YES;
}
[tblContentList reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Cancel clicked");
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Search Clicked");
[self searchTableList];
}
I hope it's help for you
You should implement correct datasource.
Create new array of items for filtered data for first.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count = ([filteredItems count] > 0) ? [filteredItems count] : [self.allItems count];
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier: #"id"];
MyCustomItem *item = ([filteredItems count] > 0) ? filteredItems[indexPath.row] : self.allItems[indexPath.row];
[self configureCell:cell forItem:item];
return cell;
}
Configure searching:
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
NSString *searchText = searchController.searchBar.text;
if ([searchText length] == 0)
{
[filteredItems removeAllObjects];
[self.tableView reloadData];
return;
}
NSMutableArray *searchResults = [self.allItems mutableCopy];
// SKIP ALL BODY OF SEARCHING
filteredPeoples = searchResults;
[self.tableView reloadData];
}
Will work pretty.
IOS 8 delegate has been deprecated not sure if that's the problem.
The method
here's [a link]https://developer.apple.com/Library/ios/documentation/UIKit/Reference/UISearchDisplayDelegate_Protocol/index.html#//apple_ref/occ/intfm/UISearchDisplayDelegate/searchDisplayControS 8 delegate has been deprecated not sure if that's the problem.
The method
try this property instead
#property(nonatomic, assign) id< UISearchResultsUpdating > searchResultsUpdater
another better link [a link]https://developer.apple.com/library/ios/samplecode/TableSearch_UISearchController/Listings/TableSearch_obj_c_TableSearch_APLResultsTableController_m.html
When I run the application, the header view container space is there, and is visible. I'm trying to display the username inside the header view, but nothing is showing up. Here is my code so far in the tableView:
#import "HomeView.h"
#interface HomeView () <UIActionSheetDelegate, UIImagePickerControllerDelegate>
#end
#implementation HomeView
- (void)viewDidLoad {
[super viewDidLoad];
if ([PFUser currentUser]) {
NSLog(#"Welcome to the App, %#", [self.user objectForKey:#"username"]);
} else {
LoginView *loginView = [[LoginView alloc] init];
[loginView setHidesBottomBarWhenPushed:YES];
[loginView.navigationItem setHidesBackButton:YES];
[self.navigationController pushViewController:loginView animated:NO];
}
UIBarButtonItem *takePhoto = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:#selector(takePhoto:)];
self.navigationItem.rightBarButtonItem = takePhoto;
// [self.tableView registerClass:[HomeViewCell class] forCellReuseIdentifier:#"cellIdentifier"];
// [self.tableView registerNib:[UINib nibWithNibName:#"HomeViewCell" bundle:nil]
// forCellReuseIdentifier:#"cellIdentifier"];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
self.reusableSectionHeaderViews = [NSMutableSet setWithCapacity:3];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
PFQuery *query = [PFQuery queryWithClassName:#"UserPhotos"];
[query orderByDescending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error: %# %#", error, [error userInfo]);
} else {
self.userPhotos = objects;
NSLog(#"Retrieved objects: %#", self.userPhotos);
[self.tableView reloadData];
}
}];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSInteger sections = self.userPhotos.count;
// Return the number of sections.
return sections;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return 1;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (section == self.userPhotos.count) {
// Load More section
return nil;
}
HomeHeaderView *headerView = [self dequeueReusableSectionHeaderView];
if (!headerView) {
headerView = [[HomeHeaderView alloc] initWithFrame:CGRectMake( 0.0f, 0.0f, self.view.bounds.size.width, 44.0f) buttons:HomePhotoHeaderButtonsDefault];
headerView.delegate = self;
[self.reusableSectionHeaderViews addObject:headerView];
}
//Setting the username display.
PFObject *owner = [self.userPhotos objectAtIndex:section];
PFUser *user = [owner objectForKey:#"user"];
[user fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
NSString *username = user.username;
[headerView.userButton setTitle:username forState:UIControlStateNormal];
}
}];
return headerView;
}
- (HomeHeaderView *)dequeueReusableSectionHeaderView {
for (HomeHeaderView *sectionHeaderView in self.reusableSectionHeaderViews) {
if (!sectionHeaderView.superview) {
// we found a section header that is no longer visible
return sectionHeaderView;
}
}
return nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cellIdentifier";
HomeViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[HomeViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Setting the image in the cell.
PFObject *carPhoto = [self.userPhotos objectAtIndex:indexPath.row];
PFFile *imageFile = [carPhoto objectForKey:#"imageFile"];
NSURL *imageFileUrl = [[NSURL alloc] initWithString:imageFile.url];
NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl];
cell.carImage.contentMode = UIViewContentModeScaleAspectFit;
cell.carImage.image = [UIImage imageWithData:imageData];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 269;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == self.userPhotos.count) {
return 0.0f;
}
return 44.0f;
}
[user fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
NSString *username = user.username;
[headerView.userButton setTitle:username forState:UIControlStateNormal];
}
}];
The code above, you are updating the headerview UI from a background thread. You need to wrap the UI part so it performs on the main thread.
dispatch_async(dispatch_get_main_queue(), ^{
[headerView.userButton setTitle:username forState:UIControlStateNormal];
};
You need to be careful though, you are performing a background operation and then updating the header which you are reusing. There is a chance that the header is reused for a new section before the operation finishes and it is then set with the wrong username for that section. You can take care of this by not reusing the header or canceling the network operation if the header scrolls off screen before the operation finishes.
I'm stuck with parse PFIMageView via URL. I already wrote one question, moved little bit but the app still doesn't work. I put run and got this error, nothing loads.
image with errors : http://postimg.org/image/jys3hqegt/
previous question: Parse.com adding images via URL
#interface TableViewController ()
#end #implementation TableViewController
#synthesize colorsTable;
- (void) retrieveFromParse {
PFQuery *retrieveColors = [PFQuery queryWithClassName:#"Hracky1"];
[retrieveColors findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
colorsArray = [[NSArray alloc] initWithArray:objects];
}
[colorsTable reloadData];
}];
[self.colorsTable reloadData];
[self.refreshControl endRefreshing]; }
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self; }
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:#selector(retrieveFromParse)];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
self.refreshControl = refreshControl;
[refreshControl addTarget:self action:#selector(retrieveFromParse) forControlEvents:UIControlEventValueChanged]; }
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated. }
- (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 colorsArray.count; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"colorsCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
PFObject *tempObject = [colorsArray objectAtIndex:indexPath.row];
[cell.imageview setFile: [tempObject objectForKey:#"ImageURL"]];
[cell.imageview loadInBackground];
cell.cellTitle.text = [tempObject objectForKey:#"cellTitle"];
cell.cellDescript.text = [tempObject objectForKey:#"cellDescript"];
return cell; }
#end
Do you check the object of the line: [tempObject objectForKey:#"ImageURL"]?
I think you can trace the URL of the object to find some informations.