Iphone 在iOS 7中,搜索栏从headerview中消失

Iphone 在iOS 7中,搜索栏从headerview中消失,iphone,objective-c,uitableview,ios7,uisearchbar,Iphone,Objective C,Uitableview,Ios7,Uisearchbar,我有一个表视图,用于显示应用程序中的设备列表。调用ViewWillDisplay时,我将self.searchDisplayController.searchBar作为子视图添加到headerView。然后我分配self.tableView.tableHeaderView=headerView。看起来是这样的: 我向下滚动tableview,使headerview退出视图,然后通过点击单元格转到其他视图控制器。当我回到这个tableView时,向上滚动到headerView,搜索栏变为不可见,

我有一个
表视图
,用于显示应用程序中的设备列表。调用ViewWillDisplay时,我将
self.searchDisplayController.searchBar作为子视图添加到headerView
。然后我分配
self.tableView.tableHeaderView=headerView
。看起来是这样的:

我向下滚动tableview,使headerview退出视图,然后通过点击单元格转到其他视图控制器。当我回到这个tableView时,向上滚动到headerView,搜索栏变为不可见,但是点击不可见区域时,searchDisplayController被激活,取消按钮不起作用。这仅适用于iOS 7。为什么会这样?

注意:当我回到tableViewController时,只有当headerView不在视图中时才会发生这种情况。我也有同样的问题。搜索栏仍然存在,可以接收触摸事件。然而,它没有被渲染。我相信问题出在UISearchDisplaycontroller中,因为如果不使用UISearchDisplaycontroller,渲染效果会很好。我最终编写了一个定制的SearchDisplaycontroller来替换它。这是非常基本的,只做我需要的

使用它的方法与使用普通UISearchDisplayController的方法相同,但self.searchDisplayController不会返回任何内容。您必须使用另一个指针来引用自定义搜索显示控制器

self.searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar(<--outlet) contentsController:self];
看起来像是一个巨大的丑陋的作品,但唯一对我有用的。渴望听到其他选择

@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
以编程方式初始化它

mySearchDisplayController = [[SearchDisplayController alloc]initWithSearchBar:mySearchBar contentsController:self];
将搜索栏添加到tableview

self.tableView.headerView = mySearchBar;

在self.searchDisplayController上使用mySearchDisplayController作为对custon类的引用。


在我的例子中,几乎在视图出现时就重新加载了将搜索显示控制器的搜索栏保存在其标题视图中的表视图。此时搜索栏将停止渲染。当我滚动表格时,它会重新出现。还值得一提的是,我的表包含UIRefreshControl,而不是UITableViewController子类

self.searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar(<--outlet) contentsController:self];
我的修复方法是在加载表之前(并结束刷新控件刷新),快速将搜索显示控制器设置为活动,然后设置为非活动:



有点像黑客,但对我来说很有用。

使用调试器,我发现UISearchBar最初是tableHeaderView的子视图,但当它消失时,它就变成了tableView本身的子视图。这可能是由UISearchDisplayController以某种方式完成的。。。因此,我进行了以下操作,将UISearchBar简单地返回到header视图:

- (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和iOS 6上都能正常工作:)


(有必要检查searchDisplayController是否处于活动状态,否则搜索过程中sarch栏会消失)

我也有同样的问题,我可以在创建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;

多亏了这个答案:

我刚刚遇到了同样的问题。当我在结束搜索状态下调试UISearchDisplayController的委托方法时,搜索栏将成为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]));
}
我的解决方案是从当前超级视图中删除搜索栏,然后将其作为子视图再次添加到tableView中。我已经测试成功了。 希望对你有所帮助

关于

我赞同。请投票表决。我自己的分数不够

我有一个类似的问题,当我反复点击从故事板加载的搜索栏时,它会消失,调用并取消搜索。他的解决办法解决了这个问题

似乎存在一个错误,重复调用和取消搜索显示控制器并不总是将搜索栏返回到表视图

我会说我对解决方案对现有视图层次结构的依赖感到不舒服。苹果似乎在每一次重大发布中都对其进行了调整。此代码可能与iOS 8冲突


我认为一个永久性的解决方案需要苹果的修复

我也遇到了同样的问题,并测试了本文中提出的一些解决方案,但它们没有为我解决问题。 之前,我在中添加并配置了UISearchBar

 - (void)viewDidLoad
代码中我的ViewController的方法

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:searchBarView.frame];
searchBar.delegate = self;
searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
ect...
解决这个问题的方法是,我在InterfaceBuilder中添加了一个UISearchbar,在ViewController中创建了一个outlet,并将这个UISearchbar添加到我的UISearchDisplayController中

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

self.searchDisplayController=[[UISearchDisplayController alloc]initWithSearchBar:searchBar(我也遇到过类似的问题,经过一些挖掘,我发现这是UISearchBar层次结构中的一个bug。这个黑客解决方案在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);
}

使用UITableView上方的UISearchBar,然后将其设置为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;
#导入
@接口位置ViewController:UIViewController
{
布尔·伊瑟肯;
}
@属性(强,非原子)IBUISearchBar*搜索栏;
@属性(强,非原子)IBUITableView*TBV位置;
.m文件

#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];
}
#pragma标记-
#pragma标记UISearchBar委托方法
-(无效)搜索栏:(UISearchBar*)搜索栏文本更改:(NSString*)搜索文本
{
[self.searchResult removeAllObjects];
如果(searchText.length==0)
{
IsSearchOn=否;
//[filteredTableData removeAllObjects];
[self.searchBar辞职FirstResponder];
//[self.tblView reloadData];
}
其他的
{
IsSearchOn=是;
if(searchText!=nil&&![searchText IsequalString:@”“)
{
/*NSPredicate*resultPredicate=[NSPredicate predicateWithFormat:@“SELF contains[c]@”,searchText];
self.searchResult=[NSMutableArray arrayWithArray:[se]
#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];
}