UITapGestureRecognizer in custom UITableViewCell within UIPicker is not working - ios

I am trying to implement multiselect option in UIPicker using setAccessoryType in UITableViewCell and following #Suda's blog
Now the Problem is : Not getting any error but UITapGestureRecognizer is not getting recognized.
toggleSelection: is not getting called (not able to add / remove object in selectedItems).
I have searched for this problem in SO but didn't get any solution. nothing is working for me.
I have used following code
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource>
{
NSMutableArray *selectedItems;
NSArray *datasource;
}
#property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
#end
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
datasource = [[NSArray alloc] initWithObjects:#"A", #"B", #"C", #"D", #"E", nil];
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
selectedItems = [[NSMutableArray alloc] init];
}
-(NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return datasource.count;
}
-(NSString*) pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return datasource[row];
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UITableViewCell *cell = (UITableViewCell *)view;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
[cell setBackgroundColor:[UIColor clearColor]];
[cell setBounds:CGRectMake(0, 0, cell.frame.size.width - 20, 44)];
cell.tag = row;
UITapGestureRecognizer * singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(toggleSelection:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
[cell setUserInteractionEnabled:YES];
[cell addGestureRecognizer:singleTapGestureRecognizer];
// Also tried with [cell.contentView addGestureRecognizer:singleTapGestureRecognizer];
}
if ([selectedItems indexOfObject:[NSNumber numberWithInt:row]] != NSNotFound) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
} else {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
cell.textLabel.text = [datasource objectAtIndex:row];
return cell;
}
- (void)toggleSelection:(UITapGestureRecognizer *)recognizer {
NSNumber *row = [NSNumber numberWithInt:recognizer.view.tag];
NSUInteger index = [selectedItems indexOfObject:row];
if (index != NSNotFound) {
[selectedItems removeObjectAtIndex:index];
[(UITableViewCell *)(recognizer.view) setAccessoryType:UITableViewCellAccessoryNone];
} else {
[selectedItems addObject:row];
[(UITableViewCell *)(recognizer.view) setAccessoryType:UITableViewCellAccessoryCheckmark];
}
}
Any help would be appreciable.

Related

How to show selected checked TableViewCell in IOS(Objective c)

Hi friends I am new in IOS. I am creating a table view of state list. On button click I'm showing a TableView on popup. Code for creating state list is
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
selectedState = [NSMutableArray new];
UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth-50, screenHeight-50)];
mytableview = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, screenWidth-50, screenHeight-100)];
mytableview.delegate =self;
mytableview.dataSource=self;
[contentView addSubview:mytableview];
UIButton *save = [[UIButton alloc] initWithFrame:CGRectMake(0, screenHeight-100, screenWidth-50, 50)];
[save setTitle:#"SAVE" forState:UIControlStateNormal];
save.titleLabel.font = [UIFont systemFontOfSize:14];
[save setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[save addTarget:self action:#selector(saveActionForState:) forControlEvents:UIControlEventTouchUpInside];
[save setBackgroundColor:[UIColor colorWithRed:41.0/255.0 green:178.0/255.0 blue:165.0/255.0 alpha:1.0]];
[contentView addSubview:save];
[[KGModal sharedInstance] showWithContentView:contentView andAnimated:YES];
For table creation code is
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [stateList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CRTableViewCellIdentifier = #"cellIdentifier";
if(selectStateButton ==1){
CRTableViewCell *cell = (CRTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CRTableViewCellIdentifier];
if (cell == nil) {
cell = [[CRTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CRTableViewCellIdentifier];
}
NSString *text = [stateList objectAtIndex:[indexPath row]];
cell.textLabel.font = [UIFont systemFontOfSize:12.0];
cell.isSelected = [selectedState containsObject:text] ? YES : NO;
cell.textLabel.text = text;
return cell;
}
}
On selection of table cell checked the cell of IOS.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(selectStateButton ==1){
//[selectedStatesForSelect2 removeAllObjects];
NSString *text = [stateList objectAtIndex:[indexPath row]];
NSInteger indexings = [indexPath row]+1;
if ([selectedState containsObject:text]){
[selectedState removeObject:text];
[selectedStatesId removeObject:[NSString stringWithFormat:#"%ld", (long)indexings]];
}else{
//NSLog(#"count%lu indexing %#",(unsigned long)[selectedState count],selectedStatesId);
[selectedState addObject:text];
[selectedStatesId addObject:[NSString stringWithFormat:#"%ld", (long)indexings]];
[selectedStatesForSelect2 addObject:[NSString stringWithFormat:#"%ld", (long)indexings]];
NSLog(#"select%#count%lu",selectedStatesForSelect2,(unsigned long)[selectedState count]);
if([selectedState count] > 3){
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Hold On..." message:#"You can't select more than three states." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[selectedState removeObject:text];
[selectedStatesId removeObject:[NSString stringWithFormat:#"%ld", (long)indexings]];
}
}
}
That seen like this. When user select first time it works very good. But after closing the table view, when user again open the state list I want to show the previous selected item. Thats not working properly. I'm using a library for check "CRMultiRowSelector".Please help me.
I will give what you ask.I tried many times this.It works perfectly
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tableViewCheckMarkPreviousSelectionUpdate;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrProductSelection,*arrProductSelectDeSelectCheckMark;
NSArray *arrayFetchFromDefaults;
}
#end
#implementation ViewController
#synthesize tableViewCheckMarkPreviousSelectionUpdate;
- (void)viewDidLoad
{
[super viewDidLoad];
arrProductSelection = [[NSMutableArray alloc]initWithObjects:#"iPhone",#"iPad",#"iPod",#"iTV",#"iWatch",#"iMac",nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
arrayFetchFromDefaults = [userDefaults objectForKey:#"selectedcheckmark"];
arrProductSelectDeSelectCheckMark = [[NSMutableArray alloc]initWithArray:arrayFetchFromDefaults];
if(arrProductSelectDeSelectCheckMark.count == 0)
{
arrProductSelectDeSelectCheckMark = [[NSMutableArray alloc]init];
for(int j=0;j<[arrProductSelection count];j++)
{
[arrProductSelectDeSelectCheckMark addObject:#"deselected"];
}
}
[tableViewCheckMarkPreviousSelectionUpdate reloadData];
}
#pragma mark - UITableViewDataSource Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrProductSelection.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *strCell = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
if([[arrProductSelectDeSelectCheckMark objectAtIndex:indexPath.row] isEqualToString:#"deselected"])
cell.accessoryType = UITableViewCellAccessoryNone;
else
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.textLabel.text = [arrProductSelection objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - UITableViewDelegate Methods
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
#try
{
CGPoint touchPoint = [cell convertPoint:CGPointZero toView:tableViewCheckMarkSelectionUpdate];
NSIndexPath *indexPath = [tableViewCheckMarkSelectionUpdate indexPathForRowAtPoint:touchPoint];
NSLog(#"%#",arrProductSelectDeSelectCheckMark);
if([arrProductSelectDeSelectCheckMark count]==0)
{
for(int i=0; i<[arrProductSelection count]; i++)
{
[arrProductSelectDeSelectCheckMark addObject:#"deselected"];
}
}
if([[arrProductSelectDeSelectCheckMark objectAtIndex:indexPath.row] isEqualToString:#"deselected"])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arrProductSelectDeSelectCheckMark replaceObjectAtIndex:indexPath.row withObject:#"selected"];
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
[arrProductSelectDeSelectCheckMark replaceObjectAtIndex:indexPath.row withObject:#"deselected"];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:arrProductSelectDeSelectCheckMark forKey:#"selectedcheckmark"];
[defaults synchronize];
}
#catch (NSException *exception) {
NSLog(#"The exception is-%#",exception);
}
}
#end
You have to save indexPaths and while creating the cell you have to again reassign state of cell. If it is selected or not.
In
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{}
in this method keep selected indexPaths and check for same indexPaths in cellPathForRowIndexPath, if there there show as checked otherwise unchecked.

How to make textfield input view as search bar?

I have tried to get proper solution ,but I can't any programmers please give me a idea how to make.
1.is it possible to make uitextfield as uisearchbar?
UISearchBar *search=[[UISearchBar alloc]init];
search.delegate=self;
[_txtLocation setInputView:search];
2.While user types the values I need show it as overlay at the bottom of the text field...
3.Please help me to find out the solution..
To make Text Field work like Search Bar implement - (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string delegate method of UITextField. So basically, you need to implement AutoComplete feature and this how you do it.
To detect which textfield is triggered use assign tag to the textfield.
In your ViewController.h file:
#interface ViewController :
<UIViewController<UITextFieldDelegate,UITableViewDataSource, UITableViewDelegate>
{
UITableView *autocompleteTableView;
UITextField * searchtextField1;
UITextField * searchtextField2;
NSMutableArray *autoCompleteList;
NSMutableArray *initalList;
}
In your ViewController.m file:
- (void)viewDidLoad {
searchtextField1 = [[UITextField alloc]
initWithFrame:CGRectMake(5,0, 245, 33)];
searchtextField2.tag = 2;
searchtextFeild1.tag = 1;
searchtextField.placeholder = #"eg: make up";
searchtextField.textColor = [UIColor whiteColor];
//[imageView addSubview:searchtextField];
//[self.view addSubview:imageView];
autoCompleteList = [[NSMutableArray alloc] init];
searchtextField1.delegate = self;
searchtextField2.delegate = self;
autocompleteTableView = [[UITableView alloc]init];
if(screenRect.size.height == 568)
{
float X_Co_tbl = (self.view.frame.size.width - 271)/2;
[autocompleteTableView setFrame:CGRectMake(X_Co_tbl, 105, 271, 120)];
}
else if (screenRect.size.width == 414)
{
float X_Co_tbl = (self.view.frame.size.width - 281)/2;
[autocompleteTableView setFrame:CGRectMake(X_Co_tbl, 145, 281, 120)];
}
else if(screenRect.size.width == 375)
{
float X_Co_tbl = (self.view.frame.size.width - 281)/2;
[autocompleteTableView setFrame:CGRectMake(X_Co_tbl, 125, 281, 120)];
}
else
{
float X_Co_tbl = (self.view.frame.size.width - 271)/2;
[autocompleteTableView setFrame:CGRectMake(X_Co_tbl, 95, 271, 120)];
}
autocompleteTableView.delegate = self;
autocompleteTableView.dataSource = self;
autocompleteTableView.scrollEnabled = YES;
autocompleteTableView.hidden = YES;
[self.view addSubview:autocompleteTableView];
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
autocompleteTableView.hidden = YES;
return YES;
}
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
autocompleteTableView.hidden = NO;
if (textField.tag == 1) {
/// Initialize your array for searchTextFeild1;
initialList = [[NSMutableArray alloc]initWithObjects:#"Face wash",#"Morning face wash",#"Cleanser", nil];
}
if (textField.tag == 2) {
/// Initialize your array for searchTextFeild2;
initialList = [[NSMutableArray alloc]initWithObjects:#"Face wash",#"Morning face wash",#"Cleanser", nil];
}
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring
stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
/// You make Text Field work as Search Bar here
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {
// Put anything that starts with this substring into the autocompleteUrls array
// The items in this array is what will show up in the table view
[autoCompleteList removeAllObjects];
for(NSString *curString in initialList) {
//NSRange substringRange = [curString rangeOfString:substring];
if ([curString rangeOfString:substring options:NSCaseInsensitiveSearch].location != NSNotFound) {
[autoCompleteList addObject:curString];
}
}
[autocompleteTableView reloadData];
}
#pragma mark UITableViewDataSource methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return autoCompleteList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier];
}
cell.textLabel.text = [autoCompleteList objectAtIndex:indexPath.row];
return cell;
}
#pragma mark UITableViewDelegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
searchtextField.text = selectedCell.textLabel.text;
autocompleteTableView.hidden = YES;
[self goPressed];
}
In .h file
#import <UIKit/UIKit.h>
#interface SEMainVC : UIViewController <UITextFieldDelegate>{
NSMutableArray *dummyArray;
NSMutableArray *searchArray;
NSString *searchTextString;
}
#property (weak, nonatomic) IBOutlet UITextField *searchTextField;
#property (weak, nonatomic) IBOutlet UITableView *contentTableView;
- (void) setupData;
#end
In .m file
#interface SEMainVC ()
#end
#implementation SEMainVC
- (void)viewDidLoad
{
[super viewDidLoad];
//set the selector to the text field in order to change its value when edited
[self.searchTextField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
//here you set up the methods to search array and reloading the tableview
[self setupData];
[self updateSearchArray];
[self.contentTableView reloadData];
}
//setting up the data sourch for the mutable array
- (void) setupData {
dummyArray = [[NSMutableArray alloc] init];
[dummyArray addObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys:#"dummy 1", #"name" , #"image1.JPG", #"image" , #"dummy 1 description textview", #"description", nil]];
[dummyArray addObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys:#"dummy 2", #"name" , #"image1.JPG", #"image" , #"dummy 2 description textview", #"description", nil]];
[dummyArray addObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys:#"dummy 3", #"name" , #"image1.JPG", #"image" , #"dummy 3 description textview", #"description", nil]];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [searchArray 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];
}
cell.textLabel.text = [[searchArray objectAtIndex:indexPath.row] objectForKey:#"name"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"DummyDetail" sender:[NSNumber numberWithInt:indexPath.row]];
}
#pragma mark - Search Methods
-(void)textFieldDidChange:(UITextField*)textField
{
searchTextString = textField.text;
[self updateSearchArray];
}
//update seach method where the textfield acts as seach bar
-(void)updateSearchArray
{
if (searchTextString.length != 0) {
searchArray = [NSMutableArray array];
for ( NSDictionary* item in dummyArray ) {
if ([[[item objectForKey:#"name"] lowercaseString] rangeOfString:[searchTextString lowercaseString]].location != NSNotFound) {
[searchArray addObject:item];
}
}
} else {
searchArray = dummyArray;
}
[self.contentTableView reloadData];
}
#pragma mark - Table view delegate
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(NSNumber*)indexNumber
{
if([[segue identifier] isEqualToString:#"DummyDetail"]){
NSInteger index = [indexNumber integerValue];
SEDetailVC *dummyDetail = [segue destinationViewController];
dummyDetail.dummyImageString = [[searchArray objectAtIndex:index] objectForKey:#"image"];
dummyDetail.dummyTextString = [[searchArray objectAtIndex:index] objectForKey:#"description"];
dummyDetail.title = [[searchArray objectAtIndex:index] objectForKey:#"name"];
}
}
- (void)viewDidUnload {
[self setSearchTextField:nil];
[self setContentTableView:nil];
[super viewDidUnload];
}
#end

UISearchBar search not clearing old cells

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

Problems in setting imageview on a selected cell in tableview in ios

I am having an app in which I am showing some data in my tableview as shown in the ScreenShot1 below.
Screenshot1.
Now I am having an imageview On my each tableview cell.
If I select any of the cell from tableview, I want an image on that selected cell as shown in screenshot2 below.
Screenshot2.
Now If I select any other cell form tableview. I want to set my imageview's image only on those selected cells as shown in Screenshot3 below.
Below is the code I am doing.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
lblRecipe = [[UILabel alloc] initWithFrame:CGRectMake(50, 5, 600, 32)];
lblRecipe.backgroundColor = [UIColor clearColor];
lblRecipe.font = [UIFont systemFontOfSize:20.0f];
[cell.contentView addSubview:lblRecipe];
checkedimg=[[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];
[cell.contentView addSubview:checkedimg];
lblRecipe.text = [array objectAtIndex:indexPath.row];
return cell;
}
On Tableview's didselect method, what should i keep to have this kind of a functionality?
I searched a lot and there are lots of questions for this but couldn't find one for this.
So Please help me on this.
Thanks in advance.
You may be better off just subclassing UITableViewCell, as this would let you change the way the cells draw, and add a property or something of the sort to indicate this state.
To create the subclass, create a new file in Xcode, and select UITableViewCell as its superclass.
Then, within that subclass, you could implement a method called setStrikeThrough: like this that you can call on the cell you dequeue from the table:
- (void) setStrikeThrough:(BOOL) striked {
if(striked) {
// create image view here and display, if it doesn't exist
} else {
// hide image view
}
}
Then, in the view controller that holds the table, you'd call this in viewDidLoad to register your subclass with the table view:
[_tableView registerClass:[YourAmazingTableCell class] forCellReuseIdentifier:#"AmazingCellSubclass"];
You would then alter your tableView:cellForRowAtIndexPath: to be something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"AmazingCellSubclass";
YourAmazingTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[YourAmazingTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// here you would look up if this row should be selected
[cell setStrikeThrough:YES];
// Set up the remainder of the cell, again based on the row
cell.textLabel.text = #"chilli";
return cell;
}
Try this,
Add a NSMutableArray checkedCellArray, as property and alloc init.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UILabel *labelRecipe = [[UILabel alloc] initWithFrame:CGRectMake(50, 5, 600, 32)];
labelRecipe.backgroundColor = [UIColor clearColor];
labelRecipe.font = [UIFont systemFontOfSize:20.0f];
labelRecipe.tag = kRecipeTag;//a tag to label
[cell.contentView addSubview:labelRecipe];
UIImageView *checkedimg = [[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];
[checkedimg setImage:[UIImage imageNamed:#"checked.png"];
checkedimg.tag = kCheckedImageTag;//a tag to imageView
[cell.contentView addSubview:checkedimg];
checkedimg.hidden = YES;
}
UILabel *labelRecipe = (UILabel *)[cell.contentView viewWithTag:kRecipeTag];
UIImageView *checkedimg = (UIImageView *)[cell.contentView viewWithTag:kCheckedImageTag];
if ([self.checkedCellArray containsObject:indexPath]) {
checkedimg.hidden = NO;
} else {
checkedimg.hidden = YES;
}
labelRecipe.text = [array objectAtIndex:indexPath.row];
return cell;
}
and in didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (![self.checkedCellArray containsObject:indexPath]) {
[self.checkedCellArray addObject:indexPath];
}
NSArray* rowsToReload = [NSArray arrayWithObjects:indexPath, nil];
[UITableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];
}
Oky hear you can do like this
just subclass the tableview cell
in CustomCell.h file
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell
#property (nonatomic,retain)UIImageView *dashImageView; //add a property of image view
#end
in CustomCell.m file
#import "CustomCell.h"
#implementation CustomCell
{
BOOL isCellSelected; //add this to check
}
#synthesize dashImageView = _dashImageView; //synthesize it
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
isCellSelected = NO;//initially set it no
_dashImageView = [[UIImageView alloc]initWithFrame:CGRectMake(self.bounds.origin.x + 15, self.bounds.origin.y + 10, self.bounds.size.width, 15.0f)];
_dashImageView.backgroundColor = [UIColor redColor];
_dashImageView.tag = 12345;
_dashImageView.hidden = YES;
[self.contentView addSubview:_dashImageView];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if(selected)
{
UIImageView *dashImageVIew = (UIImageView *)[self viewWithTag:12345];
if(dashImageVIew)
{
if(!isCellSelected)
{
dashImageVIew.hidden = NO;
isCellSelected = YES;
}
else
{
dashImageVIew.hidden = YES;
isCellSelected = NO;
}
}
}
}
EDIT:2 *For selecting both section and row for the table view*
there is no change in the custom cell only change in the controller so that u hav to reflect what changes that u made to tableview cell i.e weather u select or deselect
since u want select section along with the selected row.(your requirement) there are various way to do that, but i go by using some model object which contains index section and row.
for that u need to create a subclass of NSObject and name it as MySelectedIndex then in
in MySelectedIndex.h file
#import <Foundation/Foundation.h>
#interface MySelectedIndex : NSObject<NSCoding>//to store and retrieve data like user defaults, for non-property list objects, confirms to NSCoding protocol
#property (nonatomic,retain) NSNumber *selectedRow;
#property (nonatomic,retain) NSNumber *selectedSection;
- (id)initWithSelectedRow:(NSNumber *)selRow andSelectedIndex:(NSNumber *)selSection;
#end
in MySelectedIndex.m file
#import "MySelectedIndex.h"
#implementation MySelectedIndex
#synthesize selectedSection = _selectedSection;
#synthesize selectedRow = _selectedRow;
- (id)initWithSelectedRow:(NSNumber *)selRow andSelectedIndex:(NSNumber *)selSection
{
self = [super init];
if(self)
{
_selectedRow = selRow;
_selectedSection = selSection;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_selectedRow forKey:#"ROW"];
[aCoder encodeObject:_selectedSection forKey:#"SECTION"];
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if(self)
{
_selectedRow = [aDecoder decodeObjectForKey:#"ROW"];
_selectedSection = [aDecoder decodeObjectForKey:#"SECTION"];
}
return self;
}
#end
now get back to controller where u are using the table
in .m file
import it #import "CustomCell.h"
and in the method
in viewController.m
#interface SampleViewController ()<UITableViewDataSource,UITableViewDelegate>
{
NSMutableArray *indexes;//to store in defaults
NSMutableArray *indexesRed;//to red from the defaults
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//...other stuff's
indexes = [[NSMutableArray alloc]init];//initilise your arrays
indexesRed = [[NSMutableArray alloc]init];
//after initilizing your array
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"SELECTED_CELLL"];
if(data != nil)
{
indexes = [NSKeyedUnarchiver unarchiveObjectWithData:data];
[indexes retain];//you hav to retain the objects other wise u will get crash, make sure u will release it by proper memory mabagement (if u are not using ARC)
}
}
as u said u are using buttons to pop this viewcontroller so already u know where to place so put this in all the action methods(just replace where u are saving to user defaults )
and also read the comments that i put in the code
//put all these codes where u poping this viewcontroller
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:indexes];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"SELECTED_CELLL"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.navigationController popViewControllerAnimated:YES];
replace the cellForRowAtIndexPath by following code (i added in the below method)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath
{
CustomTabedCell *Cell = [tableView dequeueReusableCellWithIdentifier:#"CELL"];
if(Cell == nil)
{
Cell = [[CustomTabedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CELL"];
}
Cell.textLabel.text = #"Apple";
NSNumber *rowNum = [NSNumber numberWithInt:indexPath.row];
NSNumber *secNum = [NSNumber numberWithInt:indexPath.section];
__block BOOL isImageHidden = YES;
[indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop)
{
if(obj.selectedRow == rowNum && obj.selectedSection == secNum)
{
isImageHidden = NO;
}
}];
Cell.dashImageView.hidden = isImageHidden;
[Cell.contentView bringSubviewToFront:Cell.dashImageView];//as i notised the red dash imageview appers below the text, but in your image it is appearing above the text so put this line to bring the imageview above the text if dont want commnent this
return Cell;
}
finally in the method didSelectRowAtIndexPath replace by following method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *selSection = [NSNumber numberWithInt:indexPath.section];
NSNumber *selRow = [NSNumber numberWithInt:indexPath.row];
if([indexes count] == 0)
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
else if ([indexes count] == 1)
{
MySelectedIndex *singleIndex = [indexes objectAtIndex:0];
if(singleIndex.selectedSection == selSection & singleIndex.selectedRow == selRow)
{
[indexes removeAllObjects];
}
else
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
}
else
{
__block BOOL addSelectedRow = NO;
__block int index = -1;
[indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop) {
if(!((obj.selectedRow == selRow) & (obj.selectedSection == selSection)))
{
addSelectedRow = YES;
}
else
{
index = idx;
addSelectedRow = NO;
*stop = YES;
}
}];
if(addSelectedRow)
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
else
{
if(index >= 0)
{
[indexes removeObjectAtIndex:index];
}
}
}
NSLog(#"%#",indexes.description);
[tableView reloadData];
}
edit for not able to select more than 13 row's
in viewDidLoad
do like this
indexes = [[NSMutableArray alloc]init];
indexesRed = [[NSMutableArray alloc]init];
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"SELECTED_CELLL"];
if(data != nil)
{
indexes = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain]; //hear only u retain it
NSLog(#"%#",indexes.description);//check the description, how many objects are there in the array
NSLog(#"indexes->%d",[indexes count]);
}
//[indexes retain];//comment this
} //end of `viewDidLoad`
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTabedCell *Cell = [tableView dequeueReusableCellWithIdentifier:#"CELL"];
if(Cell == nil)
{
Cell = [[CustomTabedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CELL"];
}
Cell.textLabel.text = #"Apple";
__block BOOL isImageHidden = YES; //remove that __block qualifier
// __block NSInteger currentRow = indexPath.row;
// __block NSInteger currentSection = indexPath.section;
// [self.indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop)
// {
// NSInteger rowNum = [obj.selectedRow integerValue];
// NSInteger secNum = [obj.selectedSection integerValue];
// if(rowNum == currentRow && secNum == currentSection)
// {
// isImageHidden = NO;
// }
// }];
//comment block code and use simple for loop, looping through each obj slightly faster
for(int k = 0;k < [indexes count];k++)
{
MySelectedIndex *seletedIndex = [indexes objectAtIndex:k];
NSInteger row = [seletedIndex.selectedRow integerValue];
NSInteger sec = [seletedIndex.selectedSection integerValue];
if(row == indexPath.row & sec == indexPath.section)
{
isImageHidden = NO;
}
}
Cell.dashImageView.hidden = isImageHidden;
[Cell.contentView bringSubviewToFront:Cell.dashImageView];//as i notised the red dash imageview appers below the text, but in your image it is appearing above the text so put this line to bring the imageview above the text if dont want commnent this
return Cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *selSection = [NSNumber numberWithInt:indexPath.section];
NSNumber *selRow = [NSNumber numberWithInt:indexPath.row];
if([indexes count] == 0)
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
else if ([indexes count] == 1)
{
MySelectedIndex *singleIndex = [indexes objectAtIndex:0];
NSInteger rowNumInInt = [singleIndex.selectedRow integerValue];
NSInteger sectionInInt = [singleIndex.selectedSection integerValue];
if(sectionInInt == indexPath.section & rowNumInInt == indexPath.row)
{
[indexes removeAllObjects];
}
else
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
}
else
{
BOOL addSelectedRow = NO;
int index = -1;
for(int j = 0; j < [indexes count];j++)
{
MySelectedIndex *selectedObj = [indexes objectAtIndex:j];
NSInteger rowInt = [selectedObj.selectedRow integerValue];
NSInteger sectionInt = [selectedObj.selectedSection integerValue];
if(!(rowInt == indexPath.row && sectionInt == indexPath.section))
{
addSelectedRow = YES;
}
else
{
index = j;
addSelectedRow = NO;
// *stop = YES;
}
}
if(addSelectedRow)
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
else
{
if(index >= 0)
{
[indexes removeObjectAtIndex:index];
}
}
}
// [tableView reloadData];
NSLog(#"indexes count->%d",[indexes count]);//check each time by selecting and deselectin weateher it is working or not
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
thats it simple .. :)
hope this helps u .. :)
Try This it work good
#import "ViewController.h"
#interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
{
UITableView *menuTableView;
NSMutableArray *colorsArray,*tagvalueArray;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
menuTableView=[[UITableView alloc]initWithFrame:CGRectMake(0, 60, 320, 404) style:UITableViewStyleGrouped];
menuTableView.delegate=self;
menuTableView.dataSource=self;
menuTableView.separatorColor=[UIColor grayColor];
[self.view addSubview:menuTableView];
NSArray *serverResponseArray=[[NSArray alloc]initWithObjects:#"red",#"yellow",#"pink",#"none", nil]; // consider this array as the information you receive from DB or server
colorsArray =[[NSMutableArray alloc]init];
tagvalueArray =[[NSMutableArray alloc]init];
for (int i=0; i<serverResponseArray.count; i++) {
[colorsArray addObject:serverResponseArray[i]];
[tagvalueArray addObject:#"0"];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return colorsArray.count;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 40;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
for (UIView *view in cell.contentView.subviews) {
[view removeFromSuperview];
}
cell.textLabel.text =colorsArray[indexPath.row];
if ([[tagvalueArray objectAtIndex:indexPath.row]intValue]==1) {
UIImageView *checkedimg=[[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];
checkedimg.backgroundColor=[UIColor redColor];
[cell.contentView addSubview:checkedimg];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",colorsArray[indexPath.row]);
[tagvalueArray replaceObjectAtIndex:indexPath.row withObject:#"1"];
[menuTableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

Filtering a TableView with sections

I try to make a little program to learn more about searching a tableview about a searchbar. Meanwhile i'm in the third week trying to do this. I found many examples in different ways in the internet. The most with a searchdisplaycontroller but this way is only for a viewcontroller. i prefer a way that also works with an uiview and so i use the searchbar delegatemethod to filter my data dictionary. Normally i try as long i get handle such things by myself. But this is my nemesis. I really can't find a way to get this problem solved. Can anyone help me with my code?
Here it is.
#import "FilterDemoTableViewController.h"
#implementation FilterDemoTableViewController
#synthesize filteredTableData;
#synthesize searchBar;
#synthesize isFiltered;
#synthesize tableContents;
#synthesize Keys;
- (void)viewDidLoad
{
[super viewDidLoad];
searchBar.delegate = (id)self;
//-----------------------My TableView Data ------------------------------
NSArray *array1 = [[NSArray alloc]initWithObjects:#"Berlin",#"München",#"Stuttgart",nil];
NSArray *array2 = [[NSArray alloc]initWithObjects:#"Paris",#"Bordeaux",#"Marseille",#"Toulouse",nil];
NSArray *array3 = [[NSArray alloc]initWithObjects:#"London",#"Portsmouth",#"Oxford",#"York",#"Dover",nil];
NSArray *array4 = [[NSArray alloc]initWithObjects:#"Rom" ,#"Genua",#"Mailand",#"Florenz",nil];
NSArray *array5 = [[NSArray alloc]initWithObjects:#"Madrid",#"Barcelona",#"Toledo",#"Saragossa",#"Pamplona",nil];
NSDictionary *dictionary =[[NSDictionary alloc]initWithObjectsAndKeys:array1,#"Deutschland",array2,#"Frankreich",array3,#"Großbritannien",array4,#"Italien",array5,#"Spanien",nil];
self.tableContents = dictionary;
self.Keys = [self.tableContents allKeys];
//--------------------------------------------------------------------------
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (self.isFiltered) {
return [filteredTableData count];
} else {
return [Keys count];}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:section]];
int rowCount;
if(self.isFiltered)
rowCount = filteredTableData.count;
else
rowCount = [listData count];
return rowCount;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
NSDictionary* sectionDictionary;
if (isFiltered) {
sectionDictionary = [filteredTableData objectAtIndex:indexPath.section];
} else {
sectionDictionary = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
}
NSArray* sectionEntries = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
cell.textLabel.text = [sectionEntries objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
//I think here is something wrong but i don't know what
isFiltered = true;
filteredTableData = [[NSMutableArray alloc] init];
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in tableContents) //dictionary read
{
NSArray *array = [dictionary objectForKey:Keys]; //section of dictionary read
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:text options:NSCaseInsensitiveSearch];
if (titleResultsRange.length != 0)
[filteredTableData addObject:sTemp];
}
}
[self.tableView reloadData];
}
- (void)viewDidUnload{
[self setSearchBar:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Now i post a complete refreshed code. I tested each component of the code step by step. It works and the search is also fine (in a UITableViewController). But in this example the hole code is in a UIView. The reason, on this way it is possible to create non full-size tableviews and instanzes of tableviews. Much better for a clear Viewcontroller. I know that an UIView has no method like this reloadData but it is necessary.
Near the code end you can see the problem line. And for this last step i have no idea how i can solve this. [self.tableView reloadData];
#import "TableView.h"
#import <QuartzCore/QuartzCore.h>
#interface TableView ()
#end
#implementation TableView
#synthesize delegate;
#synthesize dropDownHeight;
#synthesize labelText;
#synthesize enabled;
#synthesize tableContents;
#synthesize Keys;
#synthesize searchBar;
#synthesize isFiltered;
#synthesize filteredTableData;
- (void)__show {
viewControl.alpha = 0.0f;
UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview:viewControl];
[UIView animateWithDuration:0.3f
animations:^{
viewControl.alpha = 1.0f;
}
completion:^(BOOL finished) {}];
}
- (void)__hide {
[UIView animateWithDuration:0.2f
animations:^{
viewControl.alpha = 0.0f;
}
completion:^(BOOL finished) {
[viewControl removeFromSuperview];
}];
}
- (void) setLabelText:(NSString *)_labelText{
[button setTitle:labelText forState:UIControlStateNormal];
}
- (void) setEnable:(BOOL)_enabled{
enabled = _enabled;
[button setEnabled:_enabled];
}
- (void) setArrayData:(NSArray *)_arrayData{
[table reloadData];
}
- (void) buttonPressed{
[self __show];
}
- (void) controlPressed{
//[viewControl removeFromSuperview];
[self __hide];
}
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(10, 0, 280, 30)];
[button setTitle:#"--Auswahl--" forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"combo_bg.png"] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:14]];
[self addSubview:button];
dropDownHeight = 706;
viewControl = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
[viewControl addTarget:self action:#selector(controlPressed) forControlEvents:UIControlEventTouchUpInside];
CGFloat x = self.frame.origin.x;
CGFloat y = (viewControl.frame.size.height - dropDownHeight)/2;
table = [[UITableView alloc] initWithFrame:CGRectMake(x, y, frame.size.width, dropDownHeight) style:UITableViewStyleGrouped];
table.dataSource = self;
table.delegate = self;
searchBar = [[UISearchBar alloc] init];
[searchBar sizeToFit];
searchBar.delegate = (id)self;
table.tableHeaderView = searchBar;
CALayer *layer = table.layer;
layer.masksToBounds = YES;
layer.cornerRadius = 2.0f;
layer.borderWidth = 1.0f;
[layer setBorderColor:[UIColor darkGrayColor].CGColor];
[viewControl addSubview:table];
CGAffineTransform rotateTable = CGAffineTransformMakeRotation(M_PI_2);
table.transform = rotateTable;
table.frame = CGRectMake(-2, -1, table.frame.size.width, table.frame.size.height);
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"gradientBackground.png"]];
[tempImageView setFrame:self->table.frame];
table.backgroundView = tempImageView;
//----------------------- TableView Daten ------------------------------
NSArray *array1 = [[NSArray alloc]initWithObjects:#"Berlin",#"München",#"Stuttgart",#"Hamburg",nil];
NSArray *array2 = [[NSArray alloc]initWithObjects:#"Paris",#"Bordeaux",#"Marseille",#"Toulouse",nil];
NSArray *array3 = [[NSArray alloc]initWithObjects:#"London",#"Portsmouth",#"Oxford",#"York",#"Dover",nil];
NSArray *array4 = [[NSArray alloc]initWithObjects:#"Rom" ,#"Genua",#"Mailand",#"Florenz",nil];
NSArray *array5 = [[NSArray alloc]initWithObjects:#"Madrid",#"Barcelona",#"Toledo",#"Saragossa",#"Pamplona",nil];
NSDictionary *dictionary =[[NSDictionary alloc]initWithObjectsAndKeys:array1,#"Deutschland",array2,#"Frankreich",array3,#"Großbritannien",array4,#"Italien",array5,#"Spanien",nil];
self.tableContents = dictionary;
self.Keys = [self.tableContents allKeys];
// ---------------------------------------------------------------------
}
return self;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if ([self tableView:tableView titleForHeaderInSection:section] != nil) {
return 40;
}
else {
return 0;
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
if (sectionTitle == nil) {
return nil;
}
// Create label with section title
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(20, 6, 300, 30);
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
label.shadowColor = [UIColor grayColor];
label.shadowOffset = CGSizeMake(0.0, 1.0);
label.font = [UIFont boldSystemFontOfSize:16];
label.text = sectionTitle;
// Create header view and add label as a subview
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
[view addSubview:label];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60.0;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section {
return [self.Keys objectAtIndex:section];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (self.isFiltered)
{
return 1;
} else {
return [Keys count];}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int rowCount;
if(self.isFiltered)
{
rowCount = [filteredTableData count];
}
else
{
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:section]];
rowCount = [listData count];
}
return rowCount;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier];
}
if (isFiltered)
{
NSString * stadt = [filteredTableData objectAtIndex:indexPath.row];
cell.textLabel.text = stadt;
}
else
{
NSDictionary* sectionDictionary;
sectionDictionary = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
NSArray* sectionEntries = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
cell.textLabel.text = [sectionEntries objectAtIndex:indexPath.row];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:[indexPath section]]];
NSUInteger row = [indexPath row];
NSString *rowValue = [listData objectAtIndex:row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
selectedIndex = [indexPath row];
[self __hide];
[button setTitle:[[NSString alloc] initWithFormat:rowValue] forState:UIControlStateNormal];
}
- (NSInteger) selectedIndex {
return selectedIndex;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = true;
[filteredTableData removeAllObjects];
for (NSString* key in self.tableContents)
{
NSArray *staedte = [self.tableContents objectForKey:key];
for (NSString *stadt in staedte)
{
NSRange titleResultsRange = [stadt rangeOfString:text options:NSCaseInsensitiveSearch];
if (titleResultsRange.length != 0)
{
[filteredTableData addObject:stadt];
}
}
}
}
[self.tableView reloadData]; //Here is the error
}
-(void)didChangeTableViewValue:(TableView *)TableView selectedIndex:(NSInteger)selectedIndex {
}
#end

Resources