Skip to content

Instantly share code, notes, and snippets.

@orta
Created May 12, 2012 17:25
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save orta/2667766 to your computer and use it in GitHub Desktop.
Save orta/2667766 to your computer and use it in GitHub Desktop.
Custom Search Bar
//
// 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
//
// 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
//
// 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