UITextField в UISearchBar в iOS 7

Я пытаюсь добиться того же внешнего вида моего UISearchBar с TextField внутри него, как в моем приложении для iOS 6. Я пытался закодировать его несколькими способами, но пока не увенчался успехом. Проблема в том, что я не могу изменить фрейм TextField с iOS 7. В результате, мой TextField занимает все пространство в NavigationBar и переопределяет UIBarButtonItem (кнопка меню) вправо. Смотрите фотографии ниже:

Screenshots

Код iOS 6: Вот как я его кодировал в iOS 6, где я мог установить рамку TextFields на то, что мне понравилось!

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];

Результат из кода выше в iOS 7: ! [взгляд на iOS 7]

Код iOS 7: Разница в iOS 7 заключается в том, что вам нужно использовать подпункты для добавления UITextField в UISearchBar/UINavigationBar. Делая это, я еще не смог изменить свой кадр. В настоящее время он перекрывает кнопку меню справа, что можно увидеть на рисунке ниже этого кода...

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 ТАК... Можно ли каким-либо образом изменить рамку subView (TextField)? :(

EDIT

Ответ вроде хромает. Чтобы заставить код работать в ios7 с кнопкой справа от TextField, TextField должен быть установлен как titleView панели навигации. Что не было в ios 6. Но будут другие глюки, и не рекомендуется использовать TextField в пределах панели поиска в iOS7. Вместо этого используйте searchDispalyController. Смотри мой ответ ниже

 self.navigationItem.titleView = sbTextField;

Ответ 1

Thanx to spotdog13. Мне наконец-то удалось настроить его для iOS 7 следующим образом:

#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;
}

Ответ 2

в iOS 7 для доступа к текстовому полю вам нужно еще раз подтвердить на уровне. Измените свой код следующим образом

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

Но лучший способ очистить backgournd UISearchBar и установить значок поиска в текстовом поле:

[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];

Ответ 3

Вы не должны помещать UITextField в UINavigationBar в iOS 7, этот виджет уже предоставляется Apple.

В iOS 7 вы можете просто использовать UISearchDisplayController с UISearchBar и установить:

searchDisplayController.displaySearchBarInNavigationBar = YES

Панель поиска появится в вашем UINavigationBar, и она будет хорошо работать с другим UIBarButtonItem без всех хаков и ручной размер рамки в исходном решении iOS 6.

Следует отметить, что если вы собираетесь добавить это в проект, который по-прежнему поддерживает ОС старше iOS 7, вам нужно убедиться, что вы поместили чек вокруг звонка, или ваше приложение выйдет из строя при запуске более старых ОС.

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

См. этот раздел руководства по переходу iOS 7: https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/Bars.html

В iOS 7 UISearchDisplayController включает в себя displaySearchBarInNavigationBar, которое вы можете использовать для панель поиска в панели навигации, аналогичная той, которая находится в iPhone:

Еще одно примечание - вы должны рассмотреть возможность перехода на AutoLayout вперёд, чтобы вам не пришлось выполнять все эти утомительные манипуляции с фреймами. Apple рекомендует это, и, вероятно, по уважительной причине (будущие устройства с большими экранами...?)

Ответ 4

Создайте UIView * textFieldContainer с целевым фреймом, добавьте свое текстовое поле в этот UIView, а затем добавьте этот textFieldContainer в качестве элемента навигации. т.е. ваш подход остается тем же самым, только текстовое поле входит в контейнер и вы играете с этим контейнером.

Ответ 5

Попробуйте это, я не уверен, но это должно работать так, как в iOS 7 searchbar имеет subview, и внутри этого subview есть два подзаголовка, один из которых - UITextField

UIView *searchbarview = [searchBar.subviews objectAtIndex:0];
UITextField *sbTextField = (UITextField *)[searchbarview.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];

Ответ 6

iOS6 и совместимое с iOS7 решение:

- (void)setTextFieldAsDelegate:(UIView *)inputView {
    for (UIView *view in inputView.subviews) {
        if ([view isKindOfClass:[UITextField class]]) {
            searchBarTextField = (UITextField *)view;
            searchBarTextField.delegate = self;
            break;
        } else {
            [self setTextFieldAsDelegate:view];
        }
    }
}

Ответ 7

Быстрое решение

for subView in searchBar.subviews{
        for deeperView in subView.subviews{
            if let searchField:UITextField = deeperView as? UITextField{
                searchField.layer.borderWidth = 1.0
                searchField.layer.borderColor = UIColor(red: 134/255, green: 14/255, blue: 75/255, alpha: 1).CGColor
                searchField.layer.cornerRadius = 5.0
            }
        }
    }