Подтвердить что ты не робот

SearchBar исчезает из headerview в iOS 7

У меня есть tableview для отображения списка устройств в моем приложении. Когда вызывается viewWillAppear, я добавляю self.searchDisplayController.searchBar as a subview to a headerView. Затем я назначаю self.tableView.tableHeaderView = headerView. Это выглядит так: enter image description here

Я прокручиваю таблицу вниз, чтобы headerview вышел из поля зрения, а затем перейдите к другому контроллеру вида, нажав на ячейку. Когда я вернусь к этому TableView, прокрутите вверх до headerView, searchBar станет невидимым, однако при нажатии на невидимую область активируется searchDisplayController, и кнопка отмены не работает. Это происходит только для iOS 7. Почему это происходит? enter image description here
Примечание. Это происходит только в том случае, если заголовокView не отображается, когда я возвращаюсь к tableViewController.

4b9b3361

Ответ 1

У меня была такая же проблема. Когда я перехожу к методу делегирования UISearchDisplayController в конечном состоянии поиска, searchBar становится подчиненным UIView, а не UITableView. См. Ниже код:

- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
    //My Solution: remove the searchBar away from current super view,
    //then add it as subview again to the tableView
    UISearchBar *searchBar = controller.searchBar;
    UIView *superView = searchBar.superview;
    if (![superView isKindOfClass:[UITableView class]]) {
        NSLog(@"Error here");
        [searchBar removeFromSuperview];
        [self.tableView addSubview:searchBar];
    }
    NSLog(@"%@", NSStringFromClass([superView class]));
}

Мое решение удаляет searchBar от текущего супер-представления, а затем добавляет его как subview снова в tableView. Я уже успешно тестировал. Надеюсь, что поможет!

Привет

Ответ 2

У меня такая же проблема. панель поиска все еще существует и может принимать события касания. он, однако, не отображается. Я считаю, что проблема в UISearchDisplaycontroller, потому что она отлично отображает, если я не использую UISearchDisplayController. В итоге я написал пользовательский SearchDisplaycontroller, чтобы заменить его. это очень просто и только делает то, что мне нужно.

использовать это так же, как и обычный UISearchDisplayController, но self.searchDisplayController ничего не вернет. вам придется использовать другой указатель, чтобы ссылаться на контроллер отображения пользовательского поиска.

выглядит как большая уродливая работа, но единственная, которая работала для меня. стремятся услышать альтернативы.

@protocol SearchDisplayDelegate;

@interface SearchDisplayController : NSObject<UISearchBarDelegate>

- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController;

@property(nonatomic,assign)                           id<SearchDisplayDelegate> delegate;

@property(nonatomic,getter=isActive)  BOOL            active;  // configure the view controller for searching. default is NO. animated is NO
- (void)setActive:(BOOL)visible animated:(BOOL)animated;       // animate the view controller for searching

@property(nonatomic,readonly)                         UISearchBar                *searchBar;
@property(nonatomic,readonly)                         UIViewController           *searchContentsController; // the view we are searching (often a UITableViewController)
@property(nonatomic,readonly)                         UITableView                *searchResultsTableView;   // will return non-nil. create if requested
@property(nonatomic,assign)                           id<UITableViewDataSource>   searchResultsDataSource;  // default is nil. delegate can provide
@property(nonatomic,assign)                           id<UITableViewDelegate>     searchResultsDelegate;

@end


@protocol SearchDisplayDelegate <NSObject>
// implement the protocols you need
@optional
@end

реализация

@implementation SearchDisplayController {
    UISearchBar *_searchBar;
    UIViewController *_viewController;
    UITableView *_searchResultsTableView;
    UIView *_overLay;
}

- (void)dealloc {
    [_searchBar release];
    [_searchResultsTableView release];
    [_overLay release];
    [super dealloc];
}

- (UIViewController *)searchContentsController {
    return _viewController;
}

- (UITableView *)searchResultsTableView {
    return _searchResultsTableView;
}

- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController {
    self = [super init];
    if (self) {
        _searchBar = [searchBar retain];
        _searchBar.delegate = self;
        _viewController = viewController;
        _searchResultsTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(_searchBar.frame), _viewController.view.frame.size.width, _viewController.view.frame.size.height - CGRectGetMaxY(_searchBar.frame))];
        _overLay = [[UIView alloc]initWithFrame:_searchResultsTableView.frame];
        _overLay.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(overLayTapped)];
        [_overLay addGestureRecognizer:tap];
        [tap release];
    }
    return self;
}
- (void)setSearchResultsDataSource:(id<UITableViewDataSource>)searchResultsDataSource {
    _searchResultsTableView.dataSource = searchResultsDataSource;
}

- (void)setSearchResultsDelegate:(id<UITableViewDelegate>)searchResultsDelegate {
    _searchResultsTableView.delegate = searchResultsDelegate;
}

- (void)overLayTapped {
    [self setActive:NO animated:YES];
    [_searchBar resignFirstResponder];
    _searchBar.text = nil;
    _searchBar.showsCancelButton = NO;
}

- (void)setActive:(BOOL)visible animated:(BOOL)animated {
    UIView *viewToAdd = nil;
    if (!_searchBar.text.length) {
        viewToAdd = _overLay;
    } else {
        viewToAdd = _searchResultsTableView;
    }
    float a = 0;
    if (visible) {
        [_viewController.view addSubview:viewToAdd];
        a = 1.0;
    }
    if ([_viewController.view respondsToSelector:@selectore(scrollEnabled)]) {
        ((UIScrollView *)_viewController.view).scrollEnabled = !visible;
    }

    if (animated) {
        [UIView animateWithDuration:0.2 animations:^{
            _overLay.alpha = a;
            _searchResultsTableView.alpha = a;
        }];
    } else {
        _overLay.alpha = a;
        _searchResultsTableView.alpha = a;
    }
}

- (void)setActive:(BOOL)active {
    [self setActive:active animated:YES];
}

#pragma mark - UISearchBar delegate protocols

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    [self setActive:YES animated:YES];
    searchBar.showsCancelButton = YES;
    [_searchResultsTableView reloadData];
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {

}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [_searchResultsTableView reloadData];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self overLayTapped];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    if (searchText.length) {
        [_overLay removeFromSuperview];
        [_viewController.view addSubview:_searchResultsTableView];
    } else {
        [_searchResultsTableView removeFromSuperview];
        [_viewController.view addSubview:_overLay];
    }
        [_searchResultsTableView reloadData];
}

@end

Обновление: о том, как использовать это прогеймически

объявить ivar

SearchDisplayController *mySearchDisplayController;

инициализировать его программно

mySearchDisplayController = [[SearchDisplayController alloc]initWithSearchBar:mySearchBar contentsController:self];

добавление панели поиска в таблицу просмотра

self.tableView.headerView = mySearchBar;

используйте mySearchDisplayController в качестве ссылки на класс custon вместо этого на self.searchDisplayController.

Ответ 3


В моем случае табличное представление, содержащее панель поиска контроллера поиска в своем представлении заголовка, перезагружалось почти сразу после появления представления. Именно в этот момент панель поиска перестала выдаваться. Когда я прокручивал стол, он снова появлялся. Также стоит отметить, что моя таблица содержала UIRefreshControl и была не подклассом UITableViewController.

Мое исправление включало активную настройку активного контроллера отображения, а затем неактивность очень быстро перед загрузкой таблицы (и завершением обновления управления обновлением):

[self.tableView reloadData];    
[self.refreshControl endRefreshing];
[self.searchDisplayController setActive:YES animated:NO];
[self.searchDisplayController setActive:NO];


Немного взлома, но это работает для меня.

Ответ 4

Я одобряю ответ Phien Tram. Пожалуйста, поддержите его. Мне не хватает очков.

У меня была аналогичная проблема, когда панель поиска, загруженная из раскадровки, исчезла, когда я неоднократно постучал по ней, вызывая и отклоняя поиск. Его решение устраняет проблему.

Кажется, что есть ошибка, при которой повторный вызов и увольнение контроллера отображения поиска не всегда возвращает панель поиска в представление таблицы.

Я скажу, что мне неудобно с зависимостью решения от существующей иерархии представлений. Кажется, что Apple перетаскивает его с каждым основным выпуском. Этот код может сломаться с iOS 8.

Я думаю, что для постоянного решения потребуется исправление Apple.

Ответ 5

Используя отладчик, я обнаружил, что UISearchBar изначально представляет собой дочерний вид tableHeaderView, но когда он исчезает, он стал дочерним элементом самого tableView. Вероятно, это было сделано UISearchDisplayController... Итак, я сделал следующий взлом, чтобы просто вернуть UISearchBar в представление заголовка:

- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];
  if(!self.searchDisplayController.isActive && self.searchBar.superview != self.tableView.tableHeaderView) {
    [self.tableView.tableHeaderView addSubview:self.searchBar];
  }
}

Кажется, отлично работает на iOS 7, а также на 6:)

(проверка того, что searchDisplayController неактивен, необходимо, в противном случае панель sarch исчезает во время поиска)

Ответ 6

У меня была такая же проблема, и я мог исправить ее, вызывая следующую строку после создания UISearchDisplayController

[self performSelector:@selector(setSearchDisplayController:) withObject:displayController];

Моя функция viewDidLoad выглядит следующим образом:

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 44)];
searchBar.placeholder = NSLocalizedString(@"Search", @"Search");

UISearchDisplayController *displayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
displayController.delegate = self;
displayController.searchResultsDataSource = self;
displayController.searchResultsDelegate = self;

[self performSelector:@selector(setSearchDisplayController:) withObject:displayController];

self.tableView.contentOffset = CGPointMake(0, 44);
self.tableView.tableHeaderView = searchBar;

Благодаря этому ответу: fooobar.com/questions/218535/...

Ответ 7

У меня возникла аналогичная проблема, и после некоторого копания я обнаружил, что это ошибка в иерархии UISearchBar. Это взломанное решение работало для меня в iOS 7, но имейте в виду, что это может нарушить будущие версии iOS:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    UIView *buggyView = [self.searchDisplayController.searchBar.subviews firstObject];
    // buggyView bounds and center are incorrect after returning from controller, so adjust them.
    buggyView.bounds = self.searchDisplayController.searchBar.bounds;
    buggyView.center = CGPointMake(CGRectGetWidth(buggyView.bounds)/2, CGRectGetHeight(buggyView.bounds)/2);
}

Ответ 8

Используйте UISearchBar над UITableView, затем сделайте IBOutlet и подключите их с владельцем файла к UISearchbar

Пример..h файл

#import <UIKit/UIKit.h>

@interface LocationViewController : UIViewController<UISearchBarDelegate>
{

   BOOL IsSearchOn;

}

@property (strong, nonatomic) IBOutlet UISearchBar *searchBar;

@property (strong, nonatomic) IBOutlet UITableView *TBVLocation;

.m file

#pragma mark -


#pragma mark UISearchBar Delegate Methods



-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText

{

    [self.searchResult removeAllObjects];

     if(searchText.length == 0)
      {
           IsSearchOn=NO;
        // [filteredTableData removeAllObjects];
           [self.searchBar resignFirstResponder];
        // [self .tblView reloadData];


     }
   else
     {
       IsSearchOn=YES;

       if(searchText != nil && ![searchText isEqualToString:@""])
       {

        /*            NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@", searchText];

        self.searchResult = [NSMutableArray arrayWithArray: [searchArray filteredArrayUsingPredicate:resultPredicate]];*/
        for(int i=0;i<[[arrCountryList valueForKey:@"country_name"] count];i++)
        {


            NSRange titleRange =    [[[[arrCountryList valueForKey:@"country_name"] objectAtIndex:i] lowercaseString] rangeOfString:[searchText lowercaseString]];

            if(titleRange.location != NSNotFound)
                [self.searchResult addObject:[arrCountryList objectAtIndex:i]];

        }

        [TBVLocation reloadData];
    }
   }

 }



- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar

 {


 [searchBar resignFirstResponder];


 }


-(void)searchBarCancelButtonClicked:(UISearchBar *) searchBar


{


  [searchBar resignFirstResponder];

  IsSearchOn=NO;

  searchBar.text = nil;

  [TBVLocation reloadData];



}

- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar

{

  [searchBar resignFirstResponder];
  return YES;
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
   searchBar.showsCancelButton = YES;
   searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
   // IsSearchOn=YES;
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar

{
    IsSearchOn=NO;
    searchBar.showsCancelButton = NO;
   [TBVLocation reloadData];
   [searchBar resignFirstResponder];
}

Он будет работать как прелесть.

Ответ 9

У меня была та же проблема и протестированы некоторые из предлагаемых здесь решений в этой теме, но они не решили проблему для меня. Ранее я добавил и настроил UISearchBar в

 - (void)viewDidLoad

метод моего ViewController в коде.

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:searchBarView.frame];
searchBar.delegate = self;
searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
ect...

Для меня это решило, что я добавил UISearchbar в InterfaceBuilder, создал выход в моем ViewController и добавил этот UISearchBar в свой UISearchDisplayController.

self.searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar(<--outlet) contentsController:self];

надеюсь, что это также может помочь некоторым людям