UISearchController:UITableView的Section索引与searchBar重叠

时间:2015-03-06 19:33:14

标签: ios uitableview uisearchbar uisearchcontroller

我正在构建一个使用新UISearchController的iOS 8应用。在与搜索控制器相关的表视图中,我使用区段索引让用户从表的一个部分快速跳转到下一个部分。它的工作正常,但部分索引与表/搜索控制器上的搜索栏重叠。有没有人遇到过这个问题,如果有的话,你是怎么解决的?以下是我初始化搜索控制器的方法:

self.resultsTableController = [self.storyboard instantiateViewControllerWithIdentifier:[SelectSpecialtySearchResultsTVC storyboardId]];
UINavigationController *searchResultsNavController = [[UINavigationController alloc]initWithRootViewController:self.resultsTableController];
self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsNavController];

self.searchController.searchResultsUpdater = self;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.searchBar.barTintColor = [UIColor colorWithHexString:kColorGrayLight];
self.searchController.searchBar.translucent = NO;
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, [self.view bounds].size.width, 44.0);
self.searchController.searchBar.delegate = self;

self.tableView.tableHeaderView = self.searchController.searchBar;

//present the search display controller within the confines of this class's table view
self.definesPresentationContext = YES;

// we want to be the delegate for our filtered table so didSelectRowAtIndexPath is called for both tables
self.resultsTableController.tableView.delegate = self;
self.searchController.delegate = self;

enter image description here

5 个答案:

答案 0 :(得分:10)

只需更改sectionIndex的背景颜色:

夫特:

    tableView.sectionIndexBackgroundColor = UIColor.clearColor()

答案 1 :(得分:2)

我知道这是一个老问题,但我已经看到这个问题出现了几次..而不是上面的解决方案更简单的答案是创建一个新的UIView与原始边界然后iOS不缩小宽度以容纳表索引。

即。在viewDidLoad

let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: searchController.searchBar.bounds.size.height))
headerView.addSubview(searchController.searchBar)
tableView.tableHeaderView = headerView

答案 2 :(得分:1)

我有类似的问题需要构建包含搜索栏的表格视图。

尝试更改以下属性的外观......这可能有助于您找到合适的解决方案。

如果您正在使用Interface Builder / Storyboard,请在Attribute Inspector中为搜索栏设置以下属性:

  • 搜索样式=最小
  • 栏位样式=默认
  • 半透明=是
  • Bar Tint = Default

Storyboard Attribute Inspector

这些属性当然可以在代码中设置:

self.searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
self.searchController.searchBar.barStyle = UIBarStyleDefault;
self.searchController.searchBar.translucent = NO;
//  By not setting the barTintColor property, it remains default
//  self.searchController.searchBar.barTintColor = [UIColor yourColor];

然后在表视图控制器代码中,设置以下UITableView属性:

//  Prepare custom colours as needed
UIColor *brightBlueColour = [UIColor colorWithRed:0.40 green:0.90 blue:1.00 alpha:1.00];

//  Set section index properties for your table view
[yourTableView setSectionIndexColor:[UIColor brownColor]];
[yourTableView setSectionIndexTrackingBackgroundColor:[UIColor brightBlueColor]];
if ([yourTableView respondsToSelector:@selector(sectionIndexBackgroundColor)])
    [yourTableView setSectionIndexBackgroundColor:[UIColor clearColor]];

//  Set additional properties for background colour
CGRect frame = self.tableView.bounds;
frame.origin.y = -frame.size.height;
UIView *viewBackground = [[UIView alloc] initWithFrame:frame];
[viewBackground setBackgroundColor:self.brightBlueColour];
[yourTableView addSubview:viewBackground];

在我看来,这种组合提供了更可接受的外观,我在使用带有搜索栏的表视图的应用程序中使用它。

答案 3 :(得分:1)

最后提出了一个可接受的解决方案来解决这个问题。这个答案建立在我上面的问题之上(我使用所有相同的代码减去这里改变的内容)。这里要注意的主要是@andrewbuilder是正确的 - 将搜索栏添加为表头视图将保证搜索栏将继续滚动;它只是像任何其他表头视图一样。

我最终做的是各种各样的事情。我在我的方法中做出的主要改变是改变了我的主控制器呈现我的搜索控制器的方式。具体来说,我从self.definesPresentationContext = YES;转到self.definesPresentationContext = NO;

这样做基本上是将您的搜索控制器呈现在主屏幕之上而不是在其中。这创建了一个设计权衡,因为您现在必须处理2个视图控制器的布局而不仅仅是一个。但那是我没事的地方。

我接下来要做的是在我的主视图控制器中创建一个指向UISearchBar的强指针,我称之为searchBar。然后,我将该属性设置为等于我的搜索控制器的searchBar并将其添加到我的子视图中,如下所示:

self.searchBar = self.searchController.searchBar;
[self.view addSubview:self.searchBar];

为了让它看起来正确,我必须确保我的桌子的x位置等于搜索栏框架的底部。您可以通过多种方式实现此目的:在代码中,在Interface Builder中,或者两者的组合。我会让你为自己找出正确的选择。

再次,这里的权衡是你必须设置两个视图控制器,使它看起来像是相同的屏幕,即使它不是(自定义导航栏,处理segue等)。这似乎是我和我的团队愿意接受的必要的邪恶。从这里开始,接下来的步骤就是弄清楚两个视图控制器上的edgesForExtendedLayout属性(以及表视图的contentInset)。我不打算在这里编写代码,因为根据他们的设计,每个人可能会有所不同。然而,这是它的要点。

如果您找到更简单的解决方案,请随时添加到此主题。我搜索的范围很广,但是UISearchController是一个非常新的控件,它上面没有很多文档/信息(及其怪癖)。

答案 4 :(得分:0)

最脏和简单的解决方案(按照您的意愿工作),只需创建第二个tableView。喜欢(Swift 3):

    tableView = UITableView(frame: CGRect.zero, style: .grouped)
    tableView.delegate = self
    tableView.dataSource = self
    tableView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(tableView)
    let cnt1 = NSLayoutConstraint(item: tableView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0)
    let cnt2 = NSLayoutConstraint(item: tableView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0)
    let cnt3 = NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: tableView, attribute: .trailing, multiplier: 1, constant: 0)
    let cnt4 = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: tableView, attribute: .bottom, multiplier: 1, constant: -1)
    constraintTableViewBottom = cnt4
    view.addConstraints([cnt1, cnt2, cnt3, cnt4])

    let tableView2 = UITableView(frame: CGRect.zero, style: .grouped)
    tableView2.sectionIndexColor = .black
    tableView2.sectionIndexBackgroundColor = .clear
    tableView2.delegate = self
    tableView2.dataSource = self
    tableView2.translatesAutoresizingMaskIntoConstraints = false
    tableView2.backgroundColor = .clear
    view.addSubview(tableView2)
    let cnt5 = NSLayoutConstraint(item: tableView2, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: 0)
    let cnt6 = NSLayoutConstraint(item: tableView2, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0)
    let cnt7 = NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: tableView2, attribute: .trailing, multiplier: 1, constant: 0)
    let cnt8 = NSLayoutConstraint(item: tableView2, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: 13)
    tableView2.addConstraint(cnt8)
    view.addConstraints([cnt5, cnt6, cnt7])

func sectionIndexTitles(for tableView: UITableView) -> [String]? {
    if tableView == self.tableView { return nil }
    if searchController.isActive && searchController.searchBar.text != "" {
        return filteredCells.keys.map { return sections[$0] }
    }
    return sections
}

func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
    self.tableView.scrollToRow(at: IndexPath(row: 0, section: index), at: .top, animated: true)
    return sections.index(of: title)!
}

final func numberOfSections(in tableView: UITableView) -> Int {
    if tableView != self.tableView { return 0 }
    return sections.count
}

,例如

final func updateSearchResults(for searchController: UISearchController) {
    filterCells(searchText: searchController.searchBar.text!)
    tableView.reloadSectionIndexTitles()
}