Skip to content

Commit

Permalink
Implement searching throughout all issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
Colin Guenther committed Oct 16, 2012
1 parent caa3a55 commit 271444f
Show file tree
Hide file tree
Showing 4 changed files with 310 additions and 130 deletions.
7 changes: 5 additions & 2 deletions iOSDevWeekly/COGUNewsViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
@class COGUDevWeeklyNewsManager;


@interface COGUNewsViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>;
@interface COGUNewsViewController : UIViewController<UISearchBarDelegate, UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate>;

@property (weak, nonatomic) IBOutlet UITableView *newsListingControl;
@property (strong, nonatomic) IBOutlet UIView *newsListingHeaderControl;

@end

Expand All @@ -26,13 +25,17 @@

@property (strong, nonatomic) COGUDevWeeklyNewsManager* newsManager;
@property (strong, nonatomic) NSFetchedResultsController* fetchedNewsResultsController;
@property (strong, nonatomic) NSFetchedResultsController* fetchedMatchingNewsResultsController;
@property (strong, nonatomic) NSMutableArray* newsListingRowHeightsCache;
@property (strong, nonatomic) NSMutableArray* matchingNewsRowHeightsCache;

@end


@interface COGUNewsViewController (Private)

- (void)_configureNewsListingControlAfterViewDidLoad;
- (NSFetchedResultsController*)_fetchedResultsControllerForTableView:(UITableView*)tableView;
- (NSMutableArray*)_rowHeightsCacheForTableView:(UITableView*)tableView;

@end
91 changes: 80 additions & 11 deletions iOSDevWeekly/COGUNewsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,31 @@
@implementation COGUNewsViewController

@synthesize newsListingControl;
@synthesize newsListingHeaderControl = _newsListingHeaderControl;
@synthesize fetchedNewsResultsController = _fetchedNewsResultsController;
@synthesize fetchedMatchingNewsResultsController = _fetchedMatchingNewsResultsController;
@synthesize newsManager = _newsManager;
@synthesize newsListingRowHeightsCache = _newsListingRowHeightsCache;
@synthesize matchingNewsRowHeightsCache = _matchingNewsRowHeightsCache;


#pragma mark UISearchBarDelegate

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;
{
NSPredicate* matchingNewsItemPredicate = [NSPredicate predicateWithFormat:@"(title CONTAINS[cd] %@) OR (explanation CONTAINS[cd] %@)", searchText, searchText];
[self.fetchedMatchingNewsResultsController.fetchRequest setPredicate:matchingNewsItemPredicate];
[self.fetchedMatchingNewsResultsController performFetch:nil];
[self.matchingNewsRowHeightsCache removeAllObjects];
[self.searchDisplayController.searchResultsTableView reloadData];
}


#pragma mark UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{
NSUInteger sectionCount = self.fetchedNewsResultsController.sections.count;
NSFetchedResultsController* controller = [self _fetchedResultsControllerForTableView:tableView];
NSUInteger sectionCount = controller.sections.count;
if (sectionCount > NSIntegerMax)
return NSIntegerMax;

Expand All @@ -42,7 +56,8 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
id<NSFetchedResultsSectionInfo> sectionInfo = self.fetchedNewsResultsController.sections[(NSUInteger)section];
NSFetchedResultsController* controller = [self _fetchedResultsControllerForTableView:tableView];
id<NSFetchedResultsSectionInfo> sectionInfo = controller.sections[(NSUInteger)section];
NSUInteger rowsCount = [sectionInfo numberOfObjects];
if (rowsCount > NSIntegerMax)
rowsCount = NSIntegerMax;
Expand All @@ -62,7 +77,7 @@ - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NS
if (cell == nil)
cell = [COGUNewsItemCell createCell];

COGUDevWeeklyNewsItem* newsItem = [self.fetchedNewsResultsController objectAtIndexPath:indexPath];
COGUDevWeeklyNewsItem* newsItem = [[self _fetchedResultsControllerForTableView:tableView] objectAtIndexPath:indexPath];
[cell configureWithNewsItem:newsItem];

return cell;
Expand All @@ -77,7 +92,7 @@ - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSIntege

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
{
id<NSFetchedResultsSectionInfo> sectionInfo = self.fetchedNewsResultsController.sections[(NSUInteger)section];
id<NSFetchedResultsSectionInfo> sectionInfo = [self _fetchedResultsControllerForTableView:tableView].sections[(NSUInteger)section];
NSString* sectionName = [[sectionInfo objects].cogu_firstObject category].userReadableName;

COGUNewsItemSectionHeaderView* view = [COGUNewsItemSectionHeaderView createView];
Expand All @@ -89,15 +104,17 @@ - (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSNumber* cachedHeightNumber = [self.newsListingRowHeightsCache cogu_objectAtLazyInitializedIndexPath:indexPath defaultObject:@(NAN)];
NSMutableArray* rowHeightsCache = [self _rowHeightsCacheForTableView:tableView];
NSNumber* cachedHeightNumber = [rowHeightsCache cogu_objectAtLazyInitializedIndexPath:indexPath defaultObject:@(NAN)];

if (![cachedHeightNumber isEqualToNumber:@(NAN)])
return cachedHeightNumber.floatValue;

COGUDevWeeklyNewsItem* newsItem = [self.fetchedNewsResultsController objectAtIndexPath:indexPath];
NSFetchedResultsController* controller = [self _fetchedResultsControllerForTableView:tableView];
COGUDevWeeklyNewsItem* newsItem = [controller objectAtIndexPath:indexPath];
CGFloat rowHeight = [COGUNewsItemCell preferredHeightWhenConfiguredWithNewsItem:newsItem inTableView:tableView];

[self.newsListingRowHeightsCache cogu_replaceObjectAtLazyInitializedIndexPath:indexPath withObject:@(rowHeight)];
[rowHeightsCache cogu_replaceObjectAtLazyInitializedIndexPath:indexPath withObject:@(rowHeight)];

return rowHeight;
}
Expand All @@ -122,7 +139,6 @@ - (void)viewDidUnload;
self.newsListingControl = nil;
self.fetchedNewsResultsController = nil;

[self setNewsListingHeaderControl:nil];
[super viewDidUnload];
}

Expand Down Expand Up @@ -156,6 +172,22 @@ - (NSFetchedResultsController*)fetchedNewsResultsController;
}


- (NSFetchedResultsController*)fetchedMatchingNewsResultsController;
{
if (_fetchedMatchingNewsResultsController)
return _fetchedMatchingNewsResultsController;

NSFetchRequest* fetchNewsItemsRequest = [[NSFetchRequest alloc] initWithEntityName:@"NewsItem"];
fetchNewsItemsRequest.sortDescriptors = @[
[NSSortDescriptor sortDescriptorWithKey:@"category.type" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:@"issue.number" ascending:NO]
];
_fetchedMatchingNewsResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchNewsItemsRequest managedObjectContext:self.newsManager.devWeeklyManagedObjectContext sectionNameKeyPath:@"category.type" cacheName:nil];

return _fetchedMatchingNewsResultsController;
}


- (NSMutableArray*)newsListingRowHeightsCache;
{
if (_newsListingRowHeightsCache)
Expand All @@ -167,6 +199,18 @@ - (NSMutableArray*)newsListingRowHeightsCache;
return _newsListingRowHeightsCache;
}


- (NSMutableArray*)matchingNewsRowHeightsCache;
{
if (_matchingNewsRowHeightsCache)
return _matchingNewsRowHeightsCache;

NSUInteger numberOfSections = (NSUInteger)self.searchDisplayController.searchResultsTableView.numberOfSections;
_matchingNewsRowHeightsCache = [NSMutableArray arrayWithCapacity:numberOfSections];

return _matchingNewsRowHeightsCache;
}

@end


Expand All @@ -177,7 +221,32 @@ @implementation COGUNewsViewController (Private)
- (void)_configureNewsListingControlAfterViewDidLoad;
{
self.newsListingControl.rowHeight = [COGUNewsItemCell preferredCellHeight];
self.newsListingControl.tableHeaderView = self.newsListingHeaderControl;
}

@end

- (NSFetchedResultsController*)_fetchedResultsControllerForTableView:(UITableView*)tableView;
{
if (tableView == self.newsListingControl)
return self.fetchedNewsResultsController;

if (tableView == self.searchDisplayController.searchResultsTableView)
return self.fetchedMatchingNewsResultsController;

ZAssert(NO, @"Must pass a known tableView");
return nil;
}


- (NSMutableArray*)_rowHeightsCacheForTableView:(UITableView*)tableView;
{
if (tableView == self.newsListingControl)
return self.newsListingRowHeightsCache;

if (tableView == self.searchDisplayController.searchResultsTableView)
return self.matchingNewsRowHeightsCache;

ZAssert(NO, @"Must pass a known tableView");
return nil;
}

@end
Loading

0 comments on commit 271444f

Please sign in to comment.