Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
like image 709
Jesper Martensson Avatar asked Sep 25 '13 14:09

Jesper Martensson


2 Answers

You should not put a UITextField in the UINavigationBar in iOS 7, this widget is already provided by Apple.

In iOS 7, you can simply use a UISearchDisplayController with a UISearchBar, and set:

searchDisplayController.displaySearchBarInNavigationBar = YES

The search bar will appear in your UINavigationBar, and it will play nice with the other UIBarButtonItems without all the hacks and manual frame sizing in your original iOS 6 solution.

One thing to note - if you are going to add this to a project that still supports OSes older than iOS 7, you'll want to make sure that you put a check around the call or your app will crash when running on older OSes.

if([searchDisplayController respondsToSelector:@selector(displaysSearchBarInNavigationBar)])
{
    searchDisplayController.displaysSearchBarInNavigationBar = YES;
}

See this section of the iOS 7 transition guide: https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/Bars.html

In iOS 7, UISearchDisplayController includes the displaysSearchBarInNavigationBar property, which you can use to put a search bar in a navigation bar, similar to the one in Calendar on iPhone:

One other note - you should consider migrating to AutoLayout going forward so you don't have to do all that tedious frame manipulation. Apple recommends it, and probably for good reason (future devices with larger screens...?)

like image 82
DiscDev Avatar answered Oct 21 '22 10:10

DiscDev


in iOS 7 to access Text Field you have to reiterate on level more. Change your code like this

for (UIView *subView in self.searchBar.subviews){
    for (UIView *ndLeveSubView in subView.subviews){
    if ([ndLeveSubView isKindOfClass:[UITextField class]])
        {
            searchBarTextField = (UITextField *)ndLeveSubView;
            break;
        }
    }
   }

But best way to clear backgournd of UISearchBar and setting searchbar icon in text field is:

[searchBar setBackgroundImage:[[UIImage alloc] init] ];//if you want to remove background of uisearchbar
UIImage *image = [UIImage imageNamed: @"search_icon.png"];
[searchBar setImage:image forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
like image 37
Adnan Aftab Avatar answered Oct 21 '22 10:10

Adnan Aftab