diff --git a/quickdialog/QRadioElement.h b/quickdialog/QRadioElement.h index a4bbfea2..2df46bb5 100644 --- a/quickdialog/QRadioElement.h +++ b/quickdialog/QRadioElement.h @@ -30,10 +30,13 @@ @property(nonatomic, assign, readwrite) NSInteger selected; @property(nonatomic, retain) NSArray *values; @property(nonatomic, strong) NSArray *itemsImageNames; +@property(nonatomic) BOOL searchable; - (QRadioElement *)initWithDict:(NSDictionary *)valuesDictionary selected:(int)selected title:(NSString *)title; - (void)createElements; +- (void)hideElementsNotMatchingSearchKey:(NSString*)searchKey; +- (void)showAllElements; - (NSObject *)selectedValue; - (void)setSelectedValue:(NSObject *)aSelected; diff --git a/quickdialog/QRadioElement.m b/quickdialog/QRadioElement.m index 35631aa3..62a8d77b 100644 --- a/quickdialog/QRadioElement.m +++ b/quickdialog/QRadioElement.m @@ -24,6 +24,7 @@ @implementation QRadioElement { @synthesize values = _values; @synthesize items = _items; @synthesize itemsImageNames = _itemsImageNames; +@synthesize searchable = _searchable; - (void)createElements { @@ -42,6 +43,34 @@ - (void)createElements { } } +// NOTE: I'm not preserving "old" hidden property values, but it's important as they could've been +// hidden on purpose in other context +- (void)hideElementsNotMatchingSearchKey:(NSString *)searchKey { + + for (QRadioItemElement *element in _internalRadioItemsSection.elements) { + + NSRange range = [element.title rangeOfString:searchKey + options:NSCaseInsensitiveSearch]; + + if (range.location == NSNotFound) { + + [element setHidden:YES]; + } else { + + [element setHidden:NO]; + } + } +} + +// NOTE: similar as above +- (void)showAllElements { + + for (QRadioItemElement *element in _internalRadioItemsSection.elements) { + + [element setHidden:NO]; + } +} + -(void)setItems:(NSArray *)items { _items = items; [self createElements]; diff --git a/quickdialog/QRadioItemElement.m b/quickdialog/QRadioItemElement.m index f90752ff..24983f1c 100644 --- a/quickdialog/QRadioItemElement.m +++ b/quickdialog/QRadioItemElement.m @@ -64,6 +64,8 @@ - (void)selected:(QuickDialogTableView *)tableView controller:(QuickDialogContro [_radioElement fieldDidEndEditing]; tableView.userInteractionEnabled = NO; + [_radioElement showAllElements]; + [NSTimer scheduledTimerWithTimeInterval:0.3 target:controller selector:@selector(popToPreviousRootElement) diff --git a/quickdialog/QuickDialogTableView.h b/quickdialog/QuickDialogTableView.h index 5e1f7773..ea98a54c 100644 --- a/quickdialog/QuickDialogTableView.h +++ b/quickdialog/QuickDialogTableView.h @@ -21,7 +21,8 @@ @class QElement; @class QRootElement; -@interface QuickDialogTableView : UITableView { +// NOTE: Conforming to protocols here, but could be refactored similar as quickDialogDatasource and delegate +@interface QuickDialogTableView : UITableView { @private diff --git a/quickdialog/QuickDialogTableView.m b/quickdialog/QuickDialogTableView.m index 7b6f0aa4..fdfa7913 100644 --- a/quickdialog/QuickDialogTableView.m +++ b/quickdialog/QuickDialogTableView.m @@ -17,6 +17,9 @@ @implementation QuickDialogTableView { BOOL _deselectRowWhenViewAppears; + + UISearchBar *_searchBar; + UISearchDisplayController *_searchDisplayController; } @synthesize root = _root; @@ -38,12 +41,57 @@ - (QuickDialogTableView *)initWithController:(QuickDialogController *)controller quickDialogDelegate = [[QuickDialogTableDelegate alloc] initForTableView:self]; self.delegate = quickDialogDelegate; + + if ([self.root respondsToSelector:@selector(searchable)]) { + + BOOL isSearchable = [[self.root valueForKey:@"searchable"] boolValue]; + + if (isSearchable) { + + _searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; + _searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar + contentsController:_controller]; + + _searchBar.delegate = self; + _searchDisplayController.delegate = self; + _searchDisplayController.searchResultsDataSource = self.dataSource; + _searchDisplayController.searchResultsDelegate = self.delegate; + + self.tableHeaderView = _searchBar; + } + } self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; } return self; } +#pragma mark UISearchBarDelegate members + +- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { + + if ([self.root respondsToSelector:@selector(showAllElements)]) { + + [self.root performSelector:@selector(showAllElements)]; + } + + [self reloadData]; +} + +#pragma mark UISearchDisplayDelegate memebers + +- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { + + if ([self.root respondsToSelector:@selector(hideElementsNotMatchingSearchKey:)]) { + + [self.root performSelector:@selector(hideElementsNotMatchingSearchKey:) + withObject:searchString]; + } + + return YES; +} + + -(void)setRoot:(QRootElement *)root{ _root = root; for (QSection *section in _root.sections) { diff --git a/sample/SampleDataBuilder.m b/sample/SampleDataBuilder.m index 6fe7547e..de200edd 100644 --- a/sample/SampleDataBuilder.m +++ b/sample/SampleDataBuilder.m @@ -297,6 +297,11 @@ + (QElement *)createRadioRoot { QRadioElement *elementWithAction = [[QRadioElement alloc] initWithItems:[NSArray arrayWithObjects:@"Ferrari", @"McLaren", @"Lotus", nil] selected:0 title:@"WithAction"]; elementWithAction.controllerAction = @"exampleAction:"; [section1 addElement:elementWithAction]; + + QRadioElement *elementWithFilter = [[QRadioElement alloc] initWithItems:@[@"Ferrari", @"McLaren", @"Lotus"] selected:0 title:@"Filtered"]; + elementWithFilter.searchable = YES; + [section1 addElement:elementWithFilter]; + [root addSection:section1]; QRadioSection *section2 = [[QRadioSection alloc] initWithItems:[NSArray arrayWithObjects:@"Football", @"Soccer", @"Formula 1", nil] selected:0 title:@"Sport"];