UA-17470720-3

Jump to content


Photo
- - - - -

Adding searchBar:textDidChange: in SCTableViewModelDataSource


  • Please log in to reply
7 replies to this topic

#1 Clément Marty

Clément Marty

    Experienced Member

  • STV 2.0
  • PipPipPipPip
  • 57 posts
Reputation: 12
Good

Posted 19 January 2012 - 12:38 PM

Hi Tarek,

I got some special actIons to do when the SearchBar.text is changing but I can't give my searchBar a delegate as STV is the searchBar delegate.

I tried to put my code in tableViewModel:customSearchResultForSearchText:autoSearchResults: but it only fires if there is some text in the searchbar. In my particular case I need to trigger all text change event if the text changes from "A" to "" (empty).

Son could you foward the searchBar:textDidChange: to SCTableViewModelDataSource as the others searchBar events before to trigger it yourself ?

- (void)searchBar:(UISearchBar *)sbar textDidChange:(NSString *)searchText

Thanks a lot.

#2 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 19 January 2012 - 03:12 PM

Hi Clem,

Thanks for the suggestion, will do. For the time being, you may also use the 'tableViewModel:customSearchResultForSearchText:autoSearchResults:' datasource method, which gets called whenever the search bar text changes. Please tell me if you need any help with this.

#3 Clément Marty

Clément Marty

    Experienced Member

  • STV 2.0
  • PipPipPipPip
  • 57 posts
Reputation: 12
Good

Posted 19 January 2012 - 04:18 PM

Tarek,

As I said, It will not fire if text becomes empty. This is my problem...

#4 David DelMonte

David DelMonte

    Forum Master

  • STV 4.0 Pro
  • PipPipPipPipPipPipPip
  • 527 posts
Reputation: 41
Excellent

Posted 28 January 2012 - 05:47 PM

@Clem et all, does anyone have a small code snippet that shows how to form a predicate in STV that filters for attributes across entities. For example, the user would enter "Smith" in the search bar, and the app will filter and show me all records with Smith as the last name.

I've torn my hair trying to figure this. The major boards give examples how to do this outside of STV.

I can filter ok from the main entity, not from the sub-entities.

THANKS

#5 Cristi Iulian

Cristi Iulian

    Starting Out

  • STV 3.0 Pro
  • Pip
  • 6 posts
Reputation: 0
Neutral

Posted 06 February 2012 - 07:28 AM

did you find a solution to that?

#6 David DelMonte

David DelMonte

    Forum Master

  • STV 4.0 Pro
  • PipPipPipPipPipPipPip
  • 527 posts
Reputation: 41
Excellent

Posted 06 February 2012 - 03:37 PM

If you're asking me... and I hope you are, then nope.

I have this code right now :


- (NSArray *)tableViewModel:(SCArrayOfItemsModel *)tableViewModel customSearchResultForSearchText:searchText autoSearchResults:(NSMutableArray *)autoSearchResults
{

NSLog(@"%s", __FUNCTION__);

NSMutableArray *tempArray = [NSMutableArray array];

for (NSManagedObject *object in tableViewModel.items)
	{


//myPredicate = [NSPredicate predicateWithFormat:@"(people.name contains[cd] %@)", searchText]; //another one for the junk heap

NSLog(@"searchText: %@", searchText); //this is ok
NSLog(@"nnobject is: %@nn", object); //this is ok

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(people.name contains[cd] %@)", searchText];

BOOL ok = [predicate evaluateWithObject:object]; // this is not ok
if (ok)
   {
	 NSLog (@"result is TRUE");
	 [tempArray addObject:object];
	  NSLog(@"nntempArray: %@nn", tempArray);
  } else {
	 NSLog (@"result is FALSE");
  }

}

NSLog(@"out of records");
autoSearchResults = tempArray;
NSLog(@"nnautoSearchResults: %@nn", autoSearchResults);

return autoSearchResults; // return my own search array


and these results:


object is: <MainEntity: 0x79c51cb0> (entity: MainEntity; id: 0x79c50880 <x-coredata://99B12EAD-002C-402C-99CA-CF5A328E67E5/MainEntity/p2> ; data: {
	audioName = 00010206120609;
	audioNo = 0;
	date = "2012-02-06 11:10:00 +0000";
	Main = "Main-0001 12.02.06";
	interpret = nil;
	keyword = "<relationship fault: 0x79c708a0 'keyword'>";
	order = 0;
	people = "<relationship fault: 0x79c708c0 'people'>";
	place = "<relationship fault: 0x79c710b0 'place'>";
	recurring = 0;
	summary = Test1;
	symbol = "<relationship fault: 0x79c71110 'symbol'>";
	type = "<relationship fault: 0x79c71170 'type'>";
})

2012-02-06 10:00:11.454 Appkeeper[42598:16c03] result is FALSE


Any / all help would be appreciated..

#7 Clément Marty

Clément Marty

    Experienced Member

  • STV 2.0
  • PipPipPipPip
  • 57 posts
Reputation: 12
Good

Posted 07 February 2012 - 01:54 PM

Hi all,

I did it work this way (using core data).

1 - put a UISearchBar (not a controller) in your UITableView or UIView.

2 - be sure to set the SearchBar of the table model to the one you created. I'm using storyboard and declared a UISearchBar IBoutlet called mySearchBar :
myTableModel.searchBar = mySearchBar;
3 - Set your SCClassDefinition and the property you want to search on this way :
myTableModel.classDefinition = myClassDef;

myTableModel.searchPropertyName = @"name"; // where name is a property of myClassDef

I expect that will help you. If you try to search on more than one field, I think that using this syntax would work (never tried it) @"name;surname;etc";


My problem was different. I need to know when the search text become empty again and original STV code won't fire any method in that case so I modify STV source this way :

- (void)searchBar:(UISearchBar *)sbar textDidChange:(NSString *)searchText
{
	NSArray *resultsArray = nil;
	
		// REMOVE THE IF CONDITION HERE
	//if([sbar.text length])
	{
		SCClassDefinition *objClassDef = [self firstClassDefinition];
		
		if(!self.searchPropertyName)
			self.searchPropertyName = objClassDef.titlePropertyName;
		
		NSArray *searchProperties;
		if([self.searchPropertyName isEqualToString:@"*"])
		{
			searchProperties = [NSMutableArray arrayWithCapacity:objClassDef.propertyDefinitionCount];
			for(int i=0; i<objClassDef.propertyDefinitionCount; i++)
				[(NSMutableArray *)searchProperties addObject:[objClassDef propertyDefinitionAtIndex:i].name];
		}
		else
		{
			searchProperties = [self.searchPropertyName componentsSeparatedByString:@";"];
		}

		NSMutableString *predicateFormat = [NSMutableString string];
		for(int i=0; i<searchProperties.count; i++)
		{
			NSString *property = [searchProperties objectAtIndex:i];
			if(i==0)
				[predicateFormat appendFormat:@"%@ contains[cd] '%@'", property, sbar.text];
			else
				[predicateFormat appendFormat:@" OR %@ contains[cd] '%@'", property, sbar.text];
		}
		NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat];
		
		@try 
		{
			resultsArray = [self.items filteredArrayUsingPredicate:predicate];
		}
		@catch (NSException * e) 
		{
			// handle any unexpected property-name behavior gracefully
			resultsArray = [NSArray array]; //empty array
			
			SCDebugLog(@"Warning: Invalid search predicate: %@.", predicate);
		}
		
		// Check for custom results
		NSArray *customResultsArray;
		if([self.dataSource conformsToProtocol:@protocol(SCTableViewModelDataSource)]
		   && [self.dataSource respondsToSelector:@selector(tableViewModel:customSearchResultForSearchText:autoSearchResults:)])
		{
			customResultsArray = [self.dataSource tableViewModel:self customSearchResultForSearchText:searchText
											   autoSearchResults:resultsArray];
			if(customResultsArray)
				resultsArray = customResultsArray;
		}
	}
		// ADD THIS POST TREATMENT TO AVOID ANY BUGS
	if(![sbar.text length])
	{
		resultsArray = nil;
	}
	
	SC_Release(filteredArray);
	filteredArray = SC_Retain(resultsArray);
	
	[self generateSections];
	[self.modeledTableView reloadData];
}



#8 David DelMonte

David DelMonte

    Forum Master

  • STV 4.0 Pro
  • PipPipPipPipPipPipPip
  • 527 posts
Reputation: 41
Excellent

Posted 07 February 2012 - 05:23 PM

Thanks Clem, I see what you are doing. First you are right about the syntax @"name;surname" works.

My issue is that - while that syntax works for items in the main entity (class), it cannot work for items in sub-entitiies.

So I have to drill-down each object looking for sub-entity objects (e.g. name.address) and add the objects that meet the predicate to the results array..

I think I've formed the predicate ok, but I cannot figure out how to filter the objects..




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users