视图控制器中的搜索栏和搜索显示控制器,其中包含 UITableView

Posted

技术标签:

【中文标题】视图控制器中的搜索栏和搜索显示控制器,其中包含 UITableView【英文标题】:Search Bar and Search Display Controller in View Controller with a UITableView in it 【发布时间】:2015-10-15 22:03:22 【问题描述】:

这里我有一个ViewController,顶部有一个搜索栏,下面有一个tableView,我希望tableView在没有搜索的时候显示所有的东西,然后如果有一些搜索,搜索的tableview会显示搜索结果。而且我已经实现了,但是出了点问题,就是tableView可以在不搜索的情况下正确显示,但是当我进行搜索时,搜索栏下方的table view什么也没显示,我NSLog out rowInSection,然后找到它是正确的,但为什么什么都没有出现? 这是代码,有人可以过去发现错误吗?提前致谢。 (我在 TableViewController 中做了同样的事情,它工作,但我切换到 ViewController,它没有工作)。

//MySearchViewController.h
@interface MySearchViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> 

@property (weak, nonatomic) IBOutlet UITableView *myTableView;


- (void)reloadView;

@end


//MySearchViewController.m
@interface MySearchViewController ()

@property NSUserDefaults *usrDefault;

@end

@implementation MySearchViewController 
    NSMutableArray *events;
    NSArray *searchResults;


- (void)viewDidLoad 
    [super viewDidLoad];

    self.usrDefault = [NSUserDefaults standardUserDefaults];
    events = [[NSMutableArray alloc] init];
    [self extractEventArrayData];



- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:YES];
    [self reloadView];


- (void)reloadView 
    NSLog(@"reloadView");
    events = [[NSMutableArray alloc] init];
    [self extractEventArrayData];
    [self.myTableView reloadData];


- (void)didReceiveMemoryWarning 
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


- (void)extractEventArrayData 
    NSArray *dataArray = [[NSArray alloc] initWithArray:[self.usrDefault objectForKey:@"eventDataArray"]];

    for (NSDate *dataObject in dataArray) 
        MyEventInfo *eventDecodedObject = [NSKeyedUnarchiver unarchiveObjectWithData:dataObject];
        [events addObject:eventDecodedObject];
    


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    if (tableView == self.searchDisplayController.searchResultsTableView) 
        NSLog(@"searchResults count:%lu",(unsigned long)[searchResults count]);
        return [searchResults count];

     else 
        return [events count];
    


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

    return 360;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"CustomTableCell";
    MyEventTableViewCell *cell = (MyEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...
    if (cell == nil) 
        cell = [[MyEventTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    

    // Display MyEventTableViewCell in the table cell
    MyEventInfo *event = nil;
    if (tableView == self.searchDisplayController.searchResultsTableView) 
        event = [searchResults objectAtIndex:indexPath.row];
     else 
        event = [events objectAtIndex:indexPath.row];
    

    cell.nameOfEvent.text = event.nameOfEvent;
    cell.imageOfEvent.image = [UIImage imageNamed:event.imageOfEvent];
    cell.timeOfEvent.text = event.timeOfEvent;
    cell.locationOfEvent.text = event.locationOfEvent;
    cell.dateOfEvent.text = event.dateOfEvent;

    return cell;


- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope

    NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"nameOfEvent contains[c] %@", searchText];
    searchResults = [events filteredArrayUsingPredicate:resultPredicate];


-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString

    [self filterContentForSearchText:searchString
                               scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                      objectAtIndex:[self.searchDisplayController.searchBar
                                                     selectedScopeButtonIndex]]];

    return YES;

【问题讨论】:

你记得设置tableview.delegate和tableView.dataSource为self吗? 是的,我确实设置了,tableview可以正确显示,但是当我想做一些搜索时,搜索控制器的tableview无法正确显示。 您是否设置了一个 UISearchDisplayController 来配合您的搜索栏?您的搜索栏是您的 tableview 的子视图吗? 是的,我在这里发布了同样的问题,可能更具体。***.com/questions/33162041/… 【参考方案1】:

首先,UISearchDisplayController 在 iOS 8 中已被弃用。您应该使用 UISearchController。我相信您使用的是 UISearchDisplayController,因为您在 Storyboard 中设置了它,而 Apple 尚未更新 Storyboard 的对象库以使用 UISearchController。但是,您仍然应该转换为 UISearchController 并在代码中实现所有内容,直到 Apple 更新 Storyboard Object Library。在代码中设置非常简单。

无论如何,对于您当前的问题,我相信这是因为您没有设置 searchDisplayController 的 searchResultsTableView 的数据源和委托。

在viewDidLoad中,你应该这样做

searchDisplayController.searchResultsTableView.delegate = self;
searchDisplayController.searchResultsTableView.dataSource = self;

仅仅设置代理和 IBOutlet“myTableView”的数据源并不能解决问题,因为一旦你开始搜索,searchDisplayController 会在当前视图的顶部呈现它自己的 tableView“searchDisplayController.searchResultsTableView”。当前视图控制器需要是 searchResultsTableView 的 dataSource 和 delegate。

希望这有效/有帮助!

【讨论】:

您好,感谢您的回答,但我已经尝试过您所说的,但没有成功。我遇到的问题是,当我进行搜索时,确实出现了一个 resultTableView,但是这个新的 tableView 只包含空白单元格!并且在控制台中我 NSLog 了行数,它看起来应该是正确的。我有点不明白为什么单元格是空白的。您能否看一下我在问题中更新的图片。非常感谢。 很高兴你知道了!【参考方案2】:

谢谢大家,我想通了,因为我写了

MyEventTableViewCell *cell = (MyEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

但应该是这样的

MyEventTableViewCell *cell = (MyEventTableViewCell *)[self.myTableView dequeueReusableCellWithIdentifier:CellIdentifier];

大错特错!

【讨论】:

以上是关于视图控制器中的搜索栏和搜索显示控制器,其中包含 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

独立的搜索栏和表格视图控制器

iPhone 核心数据驱动搜索:如何,资源?

iOS 7 导航栏中的搜索栏

如何在视图控制器中的标签栏和导航栏上全屏显示弹出视图?

如何正确配置添加到现有表视图控制器的搜索栏?

UISearchBar 与普通 UIView 中的控制器?