Filtering multiple arrays - xcode

I am trying to filter 4 arrays but I can't make it work. This is a pushed tableview that uses NSString to populate. When I type something in the search bar, the search results are from 1 Array(MARLINS) even in the others. I know the problem is in -(void)filtertContentForSearchText:. What am I missing?
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.searchResults2 count];
}
else
{
if ([testName isEqualToString:#"CES"])
return [self.CES count];
if ([testName isEqualToString:#"MARLINS"])
return [self.MARLINS count];
if ([testName isEqualToString:#"DELTA 2, NAVIGATOR"])
return [self.DELTA count];
if ([testName isEqualToString:#"CREW 2002, NAVIGATOR"])
return [self.CREW count];
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifire = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifire];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifire];
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.searchResults2 objectAtIndex:indexPath.row];
}
else
{
if ([testName isEqualToString:#"CES"]) {
cell.textLabel.text = [self.CES objectAtIndex:indexPath.row];
}
else if ([testName isEqualToString:#"MARLINS"]) {
cell.textLabel.text = [self.MARLINS objectAtIndex:indexPath.row];
}
else if ([testName isEqualToString:#"DELTA 2, NAVIGATOR"]) {
cell.textLabel.text = [self.DELTA objectAtIndex:indexPath.row];
}
else if ([testName isEqualToString:#"CREW 2002, NAVIGATOR"]) {
cell.textLabel.text = [self.CREW objectAtIndex:indexPath.row];
}
}
return cell;
}
#pragma Search Methods
-(void)filtertContentForSearchText:(NSString *)searchText scope:(NSString *)scope
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#", searchText];
self.searchResults2 = [ self.MARLINS filteredArrayUsingPredicate:predicate];
self.searchResults2 = [ self.CES filteredArrayUsingPredicate:predicate];
self.searchResults2 = [ self.CREW filteredArrayUsingPredicate:predicate];
self.searchResults2 = [ self.DELTA filteredArrayUsingPredicate:predicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filtertContentForSearchText:searchString scope:[[self.searchDisplayController.searchBar scopeButtonTitles]objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
return YES;
}
#end

(Extracting from comments into an 'answer', edited slightly to flow together better):
You have the scope parameter that you're not using inside the filter method. Pass in something useful there from shouldReloadTableForSearchString: to know which array you should be filtering.
Look at that scope variable. If its existing value is something you can use to identify which array you want to use, then at the bare minimum, you can replicate your if...else block similar to the code you have in cellForIndexPath and only filter a particular array.

Related

Repeat issue with UITableView cells

I am fully aware there are many cases of this issue here, although I am stumped and cannot resolve this on my own. I only want to display 4 cells total in my myTableView2 UITableView, but what I am finding is that my cells are being reused no doubt because of this line
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
I understand if I remove the if(!cell) line I might disable the UITableView from creating new cells, but that doesn't work because it mandates cell creation. Any thoughts? I have posted my code below.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
NSLog(#"CREATING NEW CELL");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.contentView.autoresizesSubviews = YES;
cell.contentView.clipsToBounds = YES;
}
if (tableView == self.myTableView)
{
if ([[array objectAtIndex:indexPath.row] isKindOfClass:[NSNumber class]])
{
cell.textLabel.text = [[array objectAtIndex:indexPath.row] stringValue];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
else
{
cell.textLabel.text = [array objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
}
if (tableView == self.myTableView2)
{
self.myTableView2.opaque = NO;
self.myTableView2.backgroundColor = [UIColor colorWithRed:(0.0/255.0) green:(0.0/255.0) blue:(102.0/255.0) alpha:1.0];
self.myTableView2.backgroundView = nil;
if ([[array2 objectAtIndex:indexPath.row] isKindOfClass:[NSNumber class]])
{
cell.textLabel.text = [[array2 objectAtIndex:indexPath.row] stringValue];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.numberOfLines = 0;
[cell.textLabel sizeToFit];
cell.textLabel.font = [self fontForCell];
}
else
{
cell.textLabel.text = [array2 objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.numberOfLines = 0;
[cell.textLabel sizeToFit];
cell.textLabel.font = [self fontForCell];
}
}
return cell;
}
Other pertinent data:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView==self.myTableView)
{
return [array count];
}
else if(tableView==self.myTableView2)
{
return [array2 count];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView==self.myTableView)
{
return [array count];
}
else if(tableView==self.myTableView2)
{
return [array2 count];
}
}
Solved!
Problem #1: the NSDictionary "for" loop was unnecessary and was contributing to multiple entries. I erased the loop.
Problem #2: numberOfSectionsInTableView and numberOfRowsInSection. Edited version below. Lesson learned: you want numberOfSectionsInTableView to reflect 1 if you only want one instance of your array shown. A value of 2 will cause two instances to be shown, so on and so forth.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView==self.myTableView)
{
return [array count];
}
else if(tableView==self.myTableView2)
{
return 1;
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView==self.myTableView)
{
return 5;
}
else if(tableView==self.myTableView2)
{
return [array2 count];
}
}

can i print the uitable customzie rows

my question if rows return 5 then UITableView show 0 to 5 index , but we want print the 3 to 5 any logic ??`
// Create the cell identifier
static NSString *CellIdentifier = #"CellIdentifier";
// Create the cell if cells are available with same cell identifier
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// If there are no cells available, allocate a new one with Default style
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[no objectAtIndex:indexPath.row]valueForKey:#"name"];
// Configure cell...
can i print the value customize range
Your Solution is this and it is working perfectly:
in .h
Bool drawCell;
in .m
- (void)viewDidLoad
{
drawCell=NO;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
if(indexPath.row==3)
{
drawCell=YES;
}
if(drawCell)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
cell.textLabel.text = [[no objectAtIndex:indexPath.row]valueForKey:#"name"];
}
else
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
cell.frame=CGRectMake(0, 0, 0, 0);
}
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (drawCell) {
return 100.0f;
} else {
return 0.0f;
}
}

How to search NSMutableArray with UISearchBar?

I've searched many places but could not find the answer, so I decided to set my own question.
I populate a UITableView with data from JSON. My data structure is like this:
NSMutableArray* studentList = [(NSDictionary*)[responseString JSONValue] objectForKey:#"StudentList"];
JSON:
{
"StudentList":[
{
"StudentID":"08DH11039",
"StudentFirstName":"Nguyen Lam",
"StudentLastName":"Binhh"
},
{
"StudentID":"08DH11163",
"StudentFirstName":"Nguyen Minh",
"StudentLastName":"Duc"
},
{
"StudentID":"08DH11038",
"StudentFirstName":"Nguyen Bao",
"StudentLastName":"Khuyen"
},
{
"StudentID":"08DH11037",
"StudentFirstName":"Nguyen Tran Duy",
"StudentLastName":"Phuong"
}
]
}
Add data to UITableView:
- (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];
}
NSDictionary *student = [studentList objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%d. %# %#", indexPath.row+1, [student objectForKey:#"StudentFirstName"], [student objectForKey:#"StudentLastName"]];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:15];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
I also add a UISearchBar but it didn't work:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[searchData removeAllObjects];
NSArray *student;
for(student in studentListCopy) //take the n group (eg. group1, group2, group3)
{
NSLog(#"%#", student);
NSMutableArray *newGroup = [[NSMutableArray alloc] init];
NSString *element;
for(element in student)
NSRange range = [element rangeOfString:searchString
options:NSCaseInsensitiveSearch];
if (range.length > 0) { //if the substring match
[newGroup addObject:element]; //add the element to group
}
}
if ([newGroup count] > 0) {
[searchData addObject:newGroup];
}
}
return YES;
}
Please help me to get it work. I want to search FirstName or LastName, which are displayed in TableView.
I'm new to iOS programming. Thank you very much.
I think this will be useful to you for understanding how the NSMutableArray is used with a UISearchBar and UITableView. The Example which I got from the internet is here. Maybe this will help you in solving your problem

How to center text in a UITableViewCell when accessory is UITableViewCellAccessoryCheckmark

I'm trying to keep text centred in a UITableViewCell when I have the accessoryView set to UITableViewCellAccessoryCheckmark. I'm also using a storyboard with this class.
Here's a screenshot of what I don't want.
How do I stop the text from being indented to the left?
My willDisplayCell method..
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [self cellToCheckmark]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
NSLog(#"Not Being Checked");
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.textAlignment = UITextAlignmentCenter;
if (cell.shouldIndentWhileEditing == YES) {
cell.shouldIndentWhileEditing = NO;
}
}
CellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.textAlignment = UITextAlignmentCenter;
if (indexPath.section == 0) {
switch (indexPath.row) {
case 0:
cell.textLabel.text = #"Google";
break;
case 1:
cell.textLabel.text = #"Bing";
break;
case 2:
cell.textLabel.text = #"Yahoo!";
break;
default:
break;
}
}
if (indexPath.row == [self cellToCheckmark]) {
NSLog(#"Being Checked");
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
NSLog(#"Not Being Checked");
cell.accessoryType = UITableViewCellAccessoryNone;
}
if (cell.shouldIndentWhileEditing == YES) {
cell.shouldIndentWhileEditing = NO;
}
return cell;
}
There are 2 things you need to do:
First, you need to make sure you set the table style to Default: UITableViewCellStyleDefault. All other styles use a detailTextLabel in one way or another and you won't be able to set the textLabel's alignment property.
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]
Then you can set the alignment of your cell's textLabel:
cell.textLabel.textAlignment = NSTextAlignmentCenter;
Then setting the accessory to checkmark based on whatever your data requires.
cell.accessoryType = ( myDataMatches ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone );
Screenshot
iOS 8+ solution:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
cell.textLabel.text = ...;
if (/* your condition */) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.layoutMargins = UIEdgeInsetsMake(0, 40, 0, 10);
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
cell.layoutMargins = UIEdgeInsetsMake(0, 10, 0, 10);
}
return cell;
}
There seems to be a much simpler answer (See this answer). In short, you are centering the label in the cell's content view. Instead, center it in the cell itself, then it won't move.
Tried it out, it works on iOS 11.2.
These solutions work for default cells. If you have your own custom cell, the easiest way to do it is make the label have constraints both to the left margin and the right margin, then create an outlet for your left margin constraint, and set its constant in the cellForRowAtIndexPath method:
cell.accessoryType = isChosen ? .checkmark : .none
cell.leftMarginConstraint.constant = isChosen ? 40 : 0
This way, the right margin which is added for your accessoryType is then added to the left as well.
Don't know if the problem is solve
if (/* your condition */) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.indentationLevel = 4;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
cell.indentationLevel = 0;
}

Invalid index path for use with UITableView when selecting rows beyond a certain number

- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section
{
return #"Substitutes";
}
- (int)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
int cnt=[subArray count];
return [subArray count];
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *visible = [tableView indexPathsForVisibleRows];
NSIndexPath *indexpath = (NSIndexPath*)[visible objectAtIndex:0];
if ((selectedIndexPath != nil) && (selectedIndexPath.row == indexPath.row)){
NSUInteger row = [indexPath row];
NSString *subtitle =[[subArray objectAtIndex:row] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *subDet =[[subDetArray objectAtIndex:row] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
int height = [self heightOfCellWithTitle:subtitle andSubtitle:subDet];
return(height < CONST_Cell_height ? CONST_Cell_height : height);
}
return 40.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
static NSString *CellIdentifier = #"SearchCell";
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
if ((selectedIndexPath != nil) && (selectedIndexPath.row == indexPath.row)){
cell = [self CreateMultilinesCell:CellIdentifier];
cell.textLabel.text=[[subArray objectAtIndex:row] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.detailTextLabel.text =[[subDetArray objectAtIndex:row] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
return cell;
} else {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text=[[subArray objectAtIndex:row] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.detailTextLabel.text =[[subDetArray objectAtIndex:row] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
return cell;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedIndexPath == indexPath) {
selectedIndexPath = nil;
[table reloadData];
} else {
selectedIndexPath = indexPath;
//static NSString *CellIdentifier = #"Cell";
//UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
//cell.textLabel.text=#"test";
//cell.detailTextLabel.text =#"det Test";
[table reloadData];
}
[self.table deselectRowAtIndexPath : indexPath animated : NO];
[tableView beginUpdates];
[tableView endUpdates];
}
i implemented table view using above code.when i selecting row no. 26 v or more it
expands on selection but doesn't contract on next click.& gives me error on scroll
NSInternalInconsistencyException', reason: 'Invalid index path for use with UITableView. Index paths passed to table view must contain exactly two indices specifying the section and row. Please use the category on NSIndexPath in UITableView.h if possible.'
code work smoothly for 25 rows. where i went wrong?
i got it finaly.:) selectedIndexpath gives garbage. i replace it by self.selectedIndexpath.
i didnt get why it do so on record no. 25 onwards.But this worked for me
Use like this
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:sender.tag-1 inSection:0];
CGRect rectOfCellInTableView = [objTableView rectForRowAtIndexPath:indexPath];
CGRect rectOfCellInSuperview = [objTableView convertRect:rectOfCellInTableView toView:[objTableView superview]];

Resources