【问题标题】:UISearchDisplayController configure "no results" view not to overlap tableFooterViewUISearchDisplayController 配置“无结果”视图不与 tableFooterView 重叠
【发布时间】:2016-06-22 02:54:50
【问题描述】:

我有一个系统提供的东西列表(例如品牌),这些东西用户不可编辑,但必须不时更改。

上下文

这些东西显示在表格视图中,并且可以使用默认的 UISearchDisplayController 进行搜索。但是,由于事物列表肯定不完整,我想让用户能够请求将其他事物添加到列表中。 为此,我在原始表格视图和搜索结果表格视图中都添加了一个表格页脚视图,它提供了一个发送邮件的按钮。

问题

只要搜索结果表视图仍然包含条目,它就可以正常工作。我的表格页脚视图显示在搜索结果下方,一切正常。

但是,如果没有找到某个搜索词的结果,则搜索显示控制器会在表格视图的中心显示一个“无结果”标签。这通常看起来很棒,如下所示:

但由于我的 tableFooterView 仍然显示(我希望它是!)“无结果”标签与我的页脚视图重叠,它看起来很糟糕:

我认为就我而言,我不需要“无结果”标签,因为我的页脚视图清楚地表明没有结果以及如何处理它。我也不介意,只要不重叠。

问题

我该怎么做

  • 使搜索视图不显示“无结果”标签
  • 或配置显示方式(-> 不重叠)

如果这是不可能的,我也愿意接受其他方式显示页脚视图(不是作为页脚)的建议,这不会有这个问题。但我喜欢这个解决方案,因为我可以在两种情况下(普通表格视图和搜索结果表格视图)都使用它,而无需进行任何更改。

【问题讨论】:

  • 用户 UISearch 栏而不是 UISearchDisplayController。
  • 我实际上正在使用两者。 ;-) 但是如果我只使用 UISearchBar 我将不得不自己做所有的事情,UISearchDisplayController 目前为我做的。 (比如覆盖另一个表格视图,提供取消功能等)我喜欢搜索显示控制器所做的几乎所有事情,这件事的事件,所以如果我能保留它,我会更喜欢它。
  • @Joachim Kurz:检查我的答案。
  • 如果没有地方先生,我也有相同类型的方法来添加地方。 joachim kurz 你能告诉我如何在页脚搜索表视图中添加按钮和标签吗?我更改了“无结果”文本。

标签: ios uisearchdisplaycontroller uitableview


【解决方案1】:

首先,重要的是要记住,使用UISearchDisplayController 是可定制性和便利性之间的权衡。您可以免费获得很多自动化的东西,但如果您需要大量定制,它可能不适合您的需求。它最适合作为一种插入式解决方案,如果您真的想使用它,我建议您围绕它来处理您的应用程序,而不是试图破解它的行为。

话虽如此,当没有结果时,为什么不让UITableView 返回单行?此行可以是空的,显示一些样板文本或图像(悲伤的脸或与应用匹配的幽默内容)。

如果要显示单行,UISearchDisplayController 的默认“无结果”标签将不会显示。这是许多应用程序的默认行为,例如 Instagram(查看“探索”选项卡)、Kindle 和默认的 Notes.app,尽管它们可能没有使用 UISearchDisplayController

如果您发现此解决方法不适合您的应用,您还可以尝试将“缺少品牌”视图添加到 UISearchResultsTableView 的第一部分的页眉视图中(而不是页脚视图)。这样,“无结果”标签将显示在其下方。将这个想法与单个空行结合起来效果会更好。

第三种选择是将此视图插入到UISearchResultsTableView 的顶部。这可以在每次没有结果时执行(必要时适当地删除它)或仅一次执行,使用它的 hidden 属性来显示或隐藏它。

隐藏此标签的任何其他方法都可能是 hacky,例如:https://stackoverflow.com/a/11715841/382834。虽然你当前的逻辑更容易,但它可能会在以后产生负面影响,所以它可能是最糟糕的路径。

【讨论】:

  • 非常感谢您提出的几个好建议。总是返回一排也感觉有点老套。我首先考虑将 MissingBrand 视图添加为额外的单元格或部分页脚,但感觉不对。将其设置为节页脚,我可以确定它始终位于表格视图的最后一个单元格的下方,而无需进行额外的(可能容易出错)工作。我想我应该保留没有结果的状态信息(例如用于可访问性)并只显示一些额外的 UI。
  • 关于不同的想法: hack 很聪明,是的。返回一个额外的单元格更不容易出错,所以我宁愿这样做。我尝试将其添加为表头视图,但在这种情况下,它显示在“无结果”上方,但不再显示搜索结果。不知道为什么(我所做的只是将其分配给tableHeaderView 而不是tableFooterView)。
  • 关于第三个选项:如何可靠地将视图插入到搜索显示控制器表视图之上?它只是覆盖在我的视图上,我几乎无法控制它,不是吗?我什至无法在 Storyboard 中配置表格视图来指定具有应该使用的重用标识符的单元格。或者你的意思是它应该与搜索结果表视图重叠,从而覆盖它?不确定这是否可行,因为“无结果”标签似乎漂浮在很多东西之上。我会做更多的实验,让你知道我做了什么,但再次感谢你的好建议!
  • Joachim,实际上我的意思是将视图设置为节页眉,因为我最初理解它也是节页脚。我已经编辑了这篇文章以明确这一点 - 很抱歉以前没有这样。请查看tableView:viewForHeaderInSection: 方法。
  • 至于在UISearchResultsTableView上方插入视图,我建议你开始尝试委托方法searchDisplayController:willShowSearchResultsTableView:。在那里你可以使用[self.view insertSubview:MISSING_BRANDS_VIEW aboveSubview:tableView]; 来放置视图。当然,这将是一种更通用的方法,因为您不会考虑呈现的行数。因此,在您对它的工作方式感到满意后,将添加/删除代码移至某个允许您控制该数字的方法,例如 tableView:numberOfRowsInSection:
【解决方案2】:

使用 UISearchBar 不会隐藏 Navigationbar

导入 UISearchBar 委托<UISearchBarDelegate>

不要忘记将代理连接到您的搜索栏

[yourSearchbar setDelegate:self]

然后添加这些委托方法,

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
   // Put here in search what you want.
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)aSearchBar
{
    [aSearchBar resignFirstResponder];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
    [searchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
    [searchBar resignFirstResponder];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
    [searchBar resignFirstResponder];
}

【讨论】:

    【解决方案3】:

    我所做的是检测是否有 0 个结果。如果结果为 0,我将 numberOfRowsInSection 更改为返回 1,将 heightForRowAtIndexPath 更改为返回 0,将 cellForRowAtIndexPath 更改为返回通用 UITableViewCell。

    就是这样。显示页脚的所有荣耀。

    【讨论】:

      【解决方案4】:

      我很乐意向您展示我的解决方案。

      首先我写了一些类别。第一类为我们提供UISearchDisplayController 表。

      @interface UITableViewController (YourUITableViewControllerCategory)
      - (UITableView *) tableViewSearch;
      @end
      
      @implementation UITableViewController (YourUITableViewControllerCategory)
      - (UITableView *) tableViewSearch
      {
          if ([self respondsToSelector:@selector(searchDisplayController)])
          {
              id searchDisplayController = [self performSelector:@selector(searchDisplayController)];
              if ([searchDisplayController respondsToSelector:@selector(searchResultsTableView)])
              {
                  id searchResultsTableView = [searchDisplayController performSelector:@selector(searchResultsTableView)];
                  if ([searchResultsTableView isKindOfClass:[UITableView class]]) return searchResultsTableView;
              }
          }
          return [UITableView new];
      }
      @end
      

      第二类返回特定类型的子视图数组。

      @interface UIView (YourUIViewCategory)
      - (NSArray *) viewsWithClass:(NSString *)class;
      @end
      
      @implementation UIView (YourUIViewCategory)
      - (NSArray *) viewsWithClass:(NSString *)class
      {
          NSMutableArray *array = [NSMutableArray new];
          for (UIView *view in self.subviews)
          {
              if ([view isMemberOfClass:NSClassFromString(class)])
              {
                  [array addObject:view];
              }
              [array addObjectsFromArray:[view viewsWithClass:class]];
          }
          return array;
      }
      @end
      

      现在您几乎可以搜索“无结果”标签了。您必须确保单元格中的所有标签都有tag != 0

      - (BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
      {
          for (UILabel *label in [self.tableViewSearch viewsWithClass:NSStringFromClass([UILabel class])])
          {
              if (label.tag == 0)
              {
                  // found it! do whatever you want with label
              }
          }
          return NO;
      }
      

      这只是我的方法。你可以找到自己的方式。祝你好运!

      【讨论】:

        【解决方案5】:

        使用以下代码删除“无结果”文本值

        - (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
        if (!isChangedNoResults) {
            if ([contactManager.filteredPeople count] == 0) {
                [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(changeNoResultsText:) userInfo:nil repeats:YES];
            }
        }}
        

        更改文本方法。

        - (void) changeNoResultsText:(NSTimer *)timer {
        if (isChangedNoResults) {
            [timer invalidate];
        }
        else {
            for (UIView *subview in [self.searchDisplayController.searchResultsTableView subviews]) {
                if ([subview isKindOfClass:[UILabel class]]) {
                    UILabel *targetLabel = (UILabel *)subview;
                    if ([targetLabel.text isEqualToString:@"No Results"]) {
                        NSLog(@"Changed!");
                        [targetLabel setText:@"_____"];
                        isChangedNoResults = YES;
                        [timer invalidate];
                    }
                }
            }
        }
        

        }

        或在搜索方法中执行以下代码

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

        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.001);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            for (UIView* v in self.searchDisplayController.searchResultsTableView.subviews) {
                if ([v isKindOfClass: [UILabel class]] &&
                    [[(UILabel*)v text] isEqualToString:@"No Results"]) {
                    [(UILabel*)v setText:@""];
                    break;
                }
            }
        });
        

        对我很有帮助,,,试试吧

        【讨论】:

          猜你喜欢
          • 2014-01-12
          • 2014-05-25
          • 1970-01-01
          • 1970-01-01
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-07
          相关资源
          最近更新 更多