mirror of
https://github.com/samsonjs/samhuri.net-ios.git
synced 2026-04-27 15:07:44 +00:00
Merge branch 'search'
This commit is contained in:
commit
ba08fdcfe4
2 changed files with 126 additions and 21 deletions
|
|
@ -371,11 +371,21 @@ wanted with as little input and thought as possible.</string>
|
||||||
<scene sceneID="smW-Zh-WAh">
|
<scene sceneID="smW-Zh-WAh">
|
||||||
<objects>
|
<objects>
|
||||||
<tableViewController storyboardIdentifier="Posts View Controller" title="Posts" useStoryboardIdentifierAsRestorationIdentifier="YES" id="7bK-jq-Zjz" customClass="PostsViewController" sceneMemberID="viewController">
|
<tableViewController storyboardIdentifier="Posts View Controller" title="Posts" useStoryboardIdentifierAsRestorationIdentifier="YES" id="7bK-jq-Zjz" customClass="PostsViewController" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="Posts Table View" alwaysBounceVertical="YES" indicatorStyle="white" dataMode="prototypes" style="grouped" separatorStyle="singleLineEtched" rowHeight="44" sectionHeaderHeight="10" sectionFooterHeight="10" id="r7i-6Z-zg0">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="Posts Table View" alwaysBounceVertical="YES" indicatorStyle="white" keyboardDismissMode="interactive" dataMode="prototypes" style="grouped" separatorStyle="singleLineEtched" rowHeight="44" sectionHeaderHeight="10" sectionFooterHeight="10" id="r7i-6Z-zg0">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="536"/>
|
<rect key="frame" x="0.0" y="0.0" width="600" height="536"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" red="0.66666666669999997" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.66666666669999997" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="tintColor" red="0.7953414352" green="0.0" blue="0.013255690590000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.7953414352" green="0.0" blue="0.013255690590000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<searchBar key="tableHeaderView" contentMode="redraw" barStyle="black" searchBarStyle="minimal" placeholder="Search" showsCancelButton="YES" id="QTr-jX-TNh">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="600" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
|
<color key="tintColor" red="0.96862745100000003" green="0.96862745100000003" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<color key="barTintColor" red="0.96862745100000003" green="0.96862745100000003" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<textInputTraits key="textInputTraits" returnKeyType="search" enablesReturnKeyAutomatically="YES"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="7bK-jq-Zjz" id="1Ht-4q-Rno"/>
|
||||||
|
</connections>
|
||||||
|
</searchBar>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" id="WCw-Qf-5nD" customClass="PostCell">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" id="WCw-Qf-5nD" customClass="PostCell">
|
||||||
<rect key="frame" x="0.0" y="86" width="320" height="44"/>
|
<rect key="frame" x="0.0" y="86" width="320" height="44"/>
|
||||||
|
|
@ -444,6 +454,7 @@ wanted with as little input and thought as possible.</string>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="addButton" destination="u2a-vi-nHQ" id="BNL-ge-ZGw"/>
|
<outlet property="addButton" destination="u2a-vi-nHQ" id="BNL-ge-ZGw"/>
|
||||||
<outlet property="publishButton" destination="8HS-W8-a6l" id="amK-fb-yQq"/>
|
<outlet property="publishButton" destination="8HS-W8-a6l" id="amK-fb-yQq"/>
|
||||||
|
<outlet property="searchBar" destination="QTr-jX-TNh" id="2h7-g8-bYJ"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Rux-fX-hf1" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="Rux-fX-hf1" sceneMemberID="firstResponder"/>
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,15 @@
|
||||||
#import "MBProgressHUD.h"
|
#import "MBProgressHUD.h"
|
||||||
#import "CommonUI.h"
|
#import "CommonUI.h"
|
||||||
|
|
||||||
@interface PostsViewController ()
|
@interface PostsViewController () <UISearchBarDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSArray *filteredPostCollections;
|
||||||
@property (nonatomic, strong) NSArray *postCollections;
|
@property (nonatomic, strong) NSArray *postCollections;
|
||||||
@property (nonatomic, readonly, strong) NSMutableArray *drafts;
|
@property (nonatomic, readonly, strong) NSMutableArray *drafts;
|
||||||
@property (nonatomic, readonly, strong) NSMutableArray *publishedPosts;
|
@property (nonatomic, readonly, strong) NSMutableArray *publishedPosts;
|
||||||
@property (nonatomic, strong) IBOutlet UIBarButtonItem *publishButton;
|
@property (nonatomic, strong) IBOutlet UIBarButtonItem *publishButton;
|
||||||
@property (nonatomic, strong) IBOutlet UIBarButtonItem *addButton;
|
@property (nonatomic, strong) IBOutlet UIBarButtonItem *addButton;
|
||||||
|
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
|
||||||
@property (nonatomic, weak) UILabel *titleLabel;
|
@property (nonatomic, weak) UILabel *titleLabel;
|
||||||
@property (nonatomic, weak) UILabel *statusLabel;
|
@property (nonatomic, weak) UILabel *statusLabel;
|
||||||
@property (nonatomic, copy) NSString *blogStatusText;
|
@property (nonatomic, copy) NSString *blogStatusText;
|
||||||
|
|
@ -39,6 +41,7 @@
|
||||||
@property (nonatomic, weak) NSLayoutConstraint *titleViewWidthConstraint;
|
@property (nonatomic, weak) NSLayoutConstraint *titleViewWidthConstraint;
|
||||||
@property (nonatomic, weak) NSLayoutConstraint *titleViewHeightConstraint;
|
@property (nonatomic, weak) NSLayoutConstraint *titleViewHeightConstraint;
|
||||||
@property (nonatomic, weak) NSLayoutConstraint *titleLabelTopConstraint;
|
@property (nonatomic, weak) NSLayoutConstraint *titleLabelTopConstraint;
|
||||||
|
@property(nonatomic, assign) BOOL hasAppeared;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
@ -68,11 +71,11 @@ static const NSUInteger SectionPublished = 1;
|
||||||
[self setupTitleView];
|
[self setupTitleView];
|
||||||
[self setupFontAwesomeIcons];
|
[self setupFontAwesomeIcons];
|
||||||
self.refreshControl.tintColor = [UIColor whiteColor];
|
self.refreshControl.tintColor = [UIColor whiteColor];
|
||||||
[self setupNotifications];
|
[self setupBlogNotifications];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
[self teardownNotifications];
|
[self teardownBlogNotifications];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setupTitleView {
|
- (void)setupTitleView {
|
||||||
|
|
@ -201,11 +204,21 @@ static const NSUInteger SectionPublished = 1;
|
||||||
if (self.tableView.indexPathForSelectedRow) {
|
if (self.tableView.indexPathForSelectedRow) {
|
||||||
[self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES];
|
[self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES];
|
||||||
}
|
}
|
||||||
|
[self setupKeyboardNotifications];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidAppear:(BOOL)animated {
|
||||||
|
[super viewDidAppear:animated];
|
||||||
|
if (!self.hasAppeared) {
|
||||||
|
self.hasAppeared = YES;
|
||||||
|
[self hideSearchBarAnimated:YES];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillDisappear:(BOOL)animated {
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
[super viewWillDisappear:animated];
|
[super viewWillDisappear:animated];
|
||||||
[self teardownBlogStatusTimer];
|
[self teardownBlogStatusTimer];
|
||||||
|
[self teardownKeyboardNotifications];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidLayoutSubviews {
|
- (void)viewDidLayoutSubviews {
|
||||||
|
|
@ -256,7 +269,7 @@ static const NSUInteger SectionPublished = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (PostCollection *)postCollectionForSection:(NSInteger)section {
|
- (PostCollection *)postCollectionForSection:(NSInteger)section {
|
||||||
return self.postCollections[section];
|
return [self collectionsForTableView][section];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (Post *)postForIndexPath:(NSIndexPath *)indexPath {
|
- (Post *)postForIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
|
@ -264,11 +277,13 @@ static const NSUInteger SectionPublished = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableArray *)drafts {
|
- (NSMutableArray *)drafts {
|
||||||
return [self postCollectionForSection:SectionDrafts].posts;
|
PostCollection *collection = self.postCollections[SectionDrafts];
|
||||||
|
return collection.posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableArray *)publishedPosts {
|
- (NSMutableArray *)publishedPosts {
|
||||||
return [self postCollectionForSection:SectionPublished].posts;
|
PostCollection *collection = self.postCollections[SectionPublished];
|
||||||
|
return collection.posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)insertNewObject:(id)sender {
|
- (IBAction)insertNewObject:(id)sender {
|
||||||
|
|
@ -333,24 +348,56 @@ static const NSUInteger SectionPublished = 1;
|
||||||
[self presentViewController:alertController animated:YES completion:nil];
|
[self presentViewController:alertController animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setupNotifications {
|
#pragma mark - Keyboard notifications
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(postUpdated:) name:PostUpdatedNotification object:nil];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(draftAdded:) name:DraftAddedNotification object:nil];
|
- (void)setupKeyboardNotifications {
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(draftRemoved:) name:DraftRemovedNotification object:nil];
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(publishedPostAdded:) name:PublishedPostAddedNotification object:nil];
|
[notificationCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(publishedPostRemoved:) name:PublishedPostRemovedNotification object:nil];
|
[notificationCenter addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)teardownNotifications {
|
- (void)teardownKeyboardNotifications {
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:PostUpdatedNotification object:nil];
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:DraftAddedNotification object:nil];
|
[notificationCenter removeObserver:self name:UIKeyboardWillShowNotification object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:DraftRemovedNotification object:nil];
|
[notificationCenter removeObserver:self name:UIKeyboardWillHideNotification object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:PublishedPostAddedNotification object:nil];
|
}
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:PublishedPostRemovedNotification object:nil];
|
|
||||||
|
- (void)keyboardWillShow:(NSNotification *)note {
|
||||||
|
NSValue *keyboardFrame = note.userInfo[UIKeyboardFrameEndUserInfoKey];
|
||||||
|
CGFloat keyboardHeight = keyboardFrame.CGRectValue.size.height;
|
||||||
|
UIEdgeInsets inset = self.tableView.contentInset;
|
||||||
|
inset.bottom = keyboardHeight;
|
||||||
|
self.tableView.contentInset = inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)keyboardWillHide:(NSNotification *)note {
|
||||||
|
UIEdgeInsets inset = self.tableView.contentInset;
|
||||||
|
inset.bottom = 0;
|
||||||
|
self.tableView.contentInset = inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Blog notificitons
|
||||||
|
|
||||||
|
- (void)setupBlogNotifications {
|
||||||
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||||
|
[notificationCenter addObserver:self selector:@selector(postUpdated:) name:PostUpdatedNotification object:nil];
|
||||||
|
[notificationCenter addObserver:self selector:@selector(draftAdded:) name:DraftAddedNotification object:nil];
|
||||||
|
[notificationCenter addObserver:self selector:@selector(draftRemoved:) name:DraftRemovedNotification object:nil];
|
||||||
|
[notificationCenter addObserver:self selector:@selector(publishedPostAdded:) name:PublishedPostAddedNotification object:nil];
|
||||||
|
[notificationCenter addObserver:self selector:@selector(publishedPostRemoved:) name:PublishedPostRemovedNotification object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)teardownBlogNotifications {
|
||||||
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||||
|
[notificationCenter removeObserver:self name:PostUpdatedNotification object:nil];
|
||||||
|
[notificationCenter removeObserver:self name:DraftAddedNotification object:nil];
|
||||||
|
[notificationCenter removeObserver:self name:DraftRemovedNotification object:nil];
|
||||||
|
[notificationCenter removeObserver:self name:PublishedPostAddedNotification object:nil];
|
||||||
|
[notificationCenter removeObserver:self name:PublishedPostRemovedNotification object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addPost:(Post *)post toSection:(NSUInteger)section {
|
- (void)addPost:(Post *)post toSection:(NSUInteger)section {
|
||||||
PostCollection *collection = [self postCollectionForSection:section];
|
PostCollection *collection = self.postCollections[section];
|
||||||
NSInteger row = 0;
|
NSInteger row = 0;
|
||||||
[collection.posts insertObject:post atIndex:row];
|
[collection.posts insertObject:post atIndex:row];
|
||||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
|
||||||
|
|
@ -463,8 +510,12 @@ static NSString *const StateRestorationBlogStatusTextKey = @"blogStatusText";
|
||||||
|
|
||||||
#pragma mark - Table View
|
#pragma mark - Table View
|
||||||
|
|
||||||
|
- (NSArray *)collectionsForTableView {
|
||||||
|
return self.filteredPostCollections ?: self.postCollections;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||||
return self.postCollections.count;
|
return [self collectionsForTableView].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||||
|
|
@ -518,4 +569,47 @@ static NSString *const StateRestorationBlogStatusTextKey = @"blogStatusText";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - UISearchBarDelegate methods
|
||||||
|
|
||||||
|
- (void)hideSearchBarAnimated:(BOOL)animated {
|
||||||
|
[self.tableView setContentOffset:CGPointMake(0, CGRectGetHeight(self.searchBar.bounds)) animated:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)filterPosts:(NSString *)text {
|
||||||
|
NSMutableArray *collections = nil;
|
||||||
|
if (text.length) {
|
||||||
|
collections = [NSMutableArray new];
|
||||||
|
for (PostCollection *collection in self.postCollections) {
|
||||||
|
PostCollection *filteredCollection = [[PostCollection alloc] initWithTitle:collection.title posts:@[]];
|
||||||
|
for (Post *post in collection.posts) {
|
||||||
|
BOOL titleMatches = [post.title rangeOfString:text options:NSCaseInsensitiveSearch].location != NSNotFound;
|
||||||
|
BOOL bodyMatches = [post.body rangeOfString:text options:NSCaseInsensitiveSearch].location != NSNotFound;
|
||||||
|
if (titleMatches || bodyMatches) {
|
||||||
|
[filteredCollection.posts addObject:post];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filteredCollection.posts.count) {
|
||||||
|
[collections addObject:filteredCollection];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.filteredPostCollections = collections;
|
||||||
|
[self.tableView reloadData];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
|
||||||
|
[self filterPosts:searchText];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
|
||||||
|
[self filterPosts:self.searchBar.text];
|
||||||
|
[self.searchBar resignFirstResponder];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
|
||||||
|
[self filterPosts:nil];
|
||||||
|
[self hideSearchBarAnimated:YES];
|
||||||
|
[self.searchBar resignFirstResponder];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue