Created
May 12, 2012 17:25
-
-
Save orta/2667766 to your computer and use it in GitHub Desktop.
Custom Search Bar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ARSearchBar.h | |
// Artsy Folio | |
// | |
// Created by orta therox on 18/04/2012. | |
// Released under The MIT License | |
// http://www.opensource.org/licenses/mit-license.php | |
// | |
// Copyright (c) 2012 http://art.sy. All rights reserved. | |
// | |
#import <UIKit/UIKit.h> | |
@interface ARSearchBar : UISearchBar | |
// Called from The SearchDisplayController Delegate | |
- (void)showCancelButton:(BOOL)show; | |
- (void)cancelSearchField; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ARSearchBar.m | |
// Artsy Folio | |
// | |
// Created by orta therox on 18/04/2012. | |
// Released under The MIT License | |
// http://www.opensource.org/licenses/mit-license.php | |
// | |
// Created by orta therox on 18/04/2012. | |
// Copyright (c) 2012 http://art.sy. All rights reserved. | |
// | |
[all our imports] | |
CGFloat ViewHeight = 32; | |
CGFloat ViewMargin = 6; | |
CGFloat TextfieldLeftMargin = 20; | |
CGFloat CancelAnimationDistance = 80; | |
@interface ARSearchBar (){ | |
UITextField *foundSearchTextField; | |
UIButton *overlayCancelButton; | |
} | |
@end | |
@implementation ARSearchBar | |
- (void)dealloc { | |
[[NSNotificationCenter defaultCenter] removeObserver:self]; | |
} | |
- (void)awakeFromNib { | |
[super awakeFromNib]; | |
// find textfield in subviews | |
for (int i = [self.subviews count] - 1; i >= 0; i--) { | |
UIView *subview = [self.subviews objectAtIndex:i]; | |
if ([subview.class isSubclassOfClass:[UITextField class]]) { | |
foundSearchTextField = (UITextField *)subview; | |
} | |
} | |
[self stylizeSearchTextField]; | |
[self createButton]; | |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeOriginalCancel) name:UITextFieldTextDidBeginEditingNotification object:foundSearchTextField]; | |
} | |
- (void)setFrame:(CGRect)frame { | |
frame.size.height = ViewHeight + (ViewMargin * 2) + 4; | |
[super setFrame:frame]; | |
} | |
- (void)layoutSubviews { | |
[super layoutSubviews]; | |
// resize textfield | |
CGRect frame = foundSearchTextField.frame; | |
frame.size.height = ViewHeight; | |
frame.origin.y = ViewMargin; | |
frame.origin.x = ViewMargin; | |
frame.size.width -= ViewMargin / 2; | |
foundSearchTextField.frame = frame; | |
} | |
- (void)stylizeSearchTextField { | |
// Sets the background to a static black, and remove round edges | |
for (int i = [self.subviews count] - 1; i >= 0; i--) { | |
UIView *subview = [self.subviews objectAtIndex:i]; | |
// This is the gradient behind the textfield | |
if ([subview.description hasPrefix:@"<UISearchBarBackground"]) { | |
[subview removeFromSuperview]; | |
} | |
} | |
// now change the search | |
foundSearchTextField.borderStyle = UITextBorderStyleNone; | |
foundSearchTextField.backgroundColor = [UIColor whiteColor]; | |
foundSearchTextField.background = nil; | |
foundSearchTextField.text = @""; | |
foundSearchTextField.clearButtonMode = UITextFieldViewModeNever; | |
foundSearchTextField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, TextfieldLeftMargin, 0)]; | |
foundSearchTextField.placeholder = @""; | |
foundSearchTextField.font = [UIFont serifFontWithSize:ARFontSansLarge]; | |
} | |
- (void)createButton { | |
ARFlatButton *cancelButton = [ARFlatButton buttonWithType:UIButtonTypeCustom]; | |
[[cancelButton titleLabel] setFont:[UIFont sansSerifFontWithSize:ARFontSansSmall]]; | |
NSString *title = [@"Cancel" uppercaseString]; | |
[cancelButton setTitle:title forState:UIControlStateNormal]; | |
[cancelButton setTitle:title forState:UIControlStateHighlighted]; | |
CGRect buttonFrame = cancelButton.frame; | |
buttonFrame.origin.y = ViewMargin - 1; | |
buttonFrame.size.height = ViewHeight; | |
buttonFrame.size.width = 66; | |
buttonFrame.origin.x = self.frame.size.width - buttonFrame.size.width - ViewMargin + CancelAnimationDistance; | |
cancelButton.frame = buttonFrame; | |
[cancelButton addTarget:self action:@selector(cancelSearchField) forControlEvents:UIControlEventTouchUpInside]; | |
overlayCancelButton = cancelButton; | |
[self addSubview:overlayCancelButton]; | |
[self bringSubviewToFront:overlayCancelButton]; | |
} | |
#pragma mark deal with the cancel button | |
- (void)showCancelButton:(BOOL)show { | |
CGFloat distance = show? -CancelAnimationDistance : CancelAnimationDistance; | |
[UIView animateWithDuration:0.25 animations:^{ | |
overlayCancelButton.frame = CGRectOffset(overlayCancelButton.frame, distance, 0); | |
}]; | |
} | |
- (void)removeOriginalCancel { | |
// remove the original button | |
for (int i = [self.subviews count] - 1; i >= 0; i--) { | |
UIView *subview = [self.subviews objectAtIndex:i]; | |
if ([subview.class isSubclassOfClass:[UIButton class]]) { | |
if (subview.frame.size.height != ViewHeight) { | |
subview.hidden = YES; | |
} | |
} | |
} | |
} | |
- (void)cancelSearchField { | |
// tap the original button! | |
for (int i = [self.subviews count] - 1; i >= 0; i--) { | |
UIView *subview = [self.subviews objectAtIndex:i]; | |
if ([subview.class isSubclassOfClass:[UIButton class]]) { | |
if (subview.frame.size.height != ViewHeight) { | |
UIButton *realCancel = (UIButton *)subview; | |
[realCancel sendActionsForControlEvents: UIControlEventTouchUpInside]; | |
} | |
} | |
} | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by orta therox on 18/04/2012. | |
// Released under The MIT License | |
// http://www.opensource.org/licenses/mit-license.php | |
// | |
@implementation ARSearchViewController | |
//Our custom search view needs to know when to show / hide the cancel button | |
- (void) searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller { | |
[searchBar showCancelButton:YES]; | |
[UIView animateWithDuration:0.2 animations:^{ | |
searchPlaceholderLabel.alpha = 0; | |
}]; | |
} | |
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller { | |
[searchBar showCancelButton:NO]; | |
[UIView animateWithDuration:0.2 animations:^{ | |
searchPlaceholderLabel.alpha = 1; | |
}]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment