Search code examples
iosuitextfielduinavigationbarios7uisearchbar

UITextField within UISearchBar in iOS 7


I am trying to accomplish the same look of my UISearchBar with a TextField within it, as in my iOS 6 app. I have tried to code it in several ways and not yet been successful. The problem is, I am not able to change the TextField's frame in any way since iOS 7. The result is, my TextField takes all the space in the NavigationBar and overrides the UIBarButtonItem (menu button) to the right. See pictures below:

Screenshots

iOS 6 code: This is how I coded it in iOS 6, where I could set the TextFields frame to whatever I liked!

UITextField *sbTextField = (UITextField *)[searchBar.subviews lastObject];
[sbTextField removeFromSuperview];

CGRect rect = searchBar.frame;
rect.size.height = 32;
rect.size.width = 210;
sbTextField.frame = rect;

[sbTextField setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin];


UIBarButtonItem *searchBarNavigationItem = [[UIBarButtonItem alloc]  initWithCustomView:sbTextField];

[[self navigationItem] setLeftBarButtonItem:searchBarNavigationItem];

The result from the code above in iOS 7: ![iOS 7 look]

iOS 7 code: The difference in iOS 7, is that you need to use subViews in order to add the UITextField to the UISearchBar/UINavigationBar. By doing this I have not yet been able to change its frame. It currently overlaps the menuButton to the right which can be seen in the picture below this code...

UITextField* sbTextField;
CGRect rect = subView.frame;
rect.size.height = 32;
rect.size.width = 115;

for (UIView *subView in self.searchBar.subviews){
    for (UIView *ndLeveSubView in subView.subviews){

        if ([ndLeveSubView isKindOfClass:[UITextField class]])
        {

            sbTextField = (UITextField *)ndLeveSubView;
            sbTextField.backgroundColor =[UIColor whiteColor];
            UIBarButtonItem *searchBarNavigationItem = [[UIBarButtonItem alloc] initWithCustomView:sbTextField];
            sbTextField.frame = rect;
            self.navigationItem.leftBarButtonItem = searchBarNavigationItem;
            self.navigationItem.rightBarButtonItem =  menuButton;
            [sbTextField removeFromSuperview];

             break;
        }

    }

 }
 [self.searchBar reloadInputViews];

enter image description here SO...Is it possible to change a subView's frame (TextField) in any way ? :(

EDIT

The answer is kinda lame. In order to make the code work in ios7 with a button to the right of the TextField, the TextField must be set as the titleView of the navigationBar. Which was not the case in ios 6. But there will be other glitches and it is not recommended to use TextField within searchBars in iOS7. Use searchDispalyController instead. Se my answer below

 self.navigationItem.titleView = sbTextField;

Solution

  • Thanx to spotdog13. I finally managed to make it work for iOS 7 properly in the following way:

    #define TABLE_BOTTOM_MARGIN 5
    #define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
    #define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
    #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
    #define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
    #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
    
    @interface HomeViewController ()
    
    @end
    
    @implementation HomeViewController
    
    @synthesize searchBar;
    @synthesize searchResults;
    
    - (void)viewDidLoad
    {
     if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    
    
        [searchBar sizeToFit]; // standard size
        searchBar.delegate = self;
    
        // Add search bar to navigation bar
        self.navigationItem.titleView = searchBar;
        }
    }
    
    - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
    // Manually activate search mode
    // Use animated=NO so we'll be able to immediately un-hide it again
    [self.searchDisplayController setActive:YES animated:NO];
    // Hand over control to UISearchDisplayController during the search
    // searchBar.delegate = (id <UISearchBarDelegate>)self.searchDisplayController;
    
    return YES;
    }
    
    #pragma mark <UISearchDisplayDelegate>
    - (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController
     // Un-hide the navigation bar that UISearchDisplayController hid
    [self.navigationController setNavigationBarHidden:NO animated:NO];
    }
    
    - (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController
                                               *)controller {
    searchBar = (UISearchBar *)self.navigationItem.titleView;
    // Manually resign search mode
    [searchBar resignFirstResponder];
    // Take back control of the search bar
    searchBar.delegate = self;
    }