UITableView 部分标题在前子视图上方绘制

Posted

技术标签:

【中文标题】UITableView 部分标题在前子视图上方绘制【英文标题】:UITableView section headers drawing above front subview 【发布时间】:2010-03-16 19:59:53 【问题描述】:

我有一个 UITableView,它的数据有部分。我在 tableView 顶部显示一个覆盖视图,在搜索时它会变暗:

- (UIView *)blackOverlay 
    if (!blackOverlay) 
        blackOverlay = [[UIView alloc] initWithFrame:[self overlayFrame]];
        blackOverlay.alpha = 0.75;
        blackOverlay.backgroundColor = UIColor.blackColor;
        [tableView insertSubview:blackOverlay aboveSubview:self.parentViewController.view];
    
    return blackOverlay;

只要 tableView 不包含部分,它就可以完美地工作。当 tableView 确实包含部分并且 tableView 更新时(例如当视图在从导航控制器堆栈中弹出视图后重新出现时),部分标题将呈现在 blackOverlay 之上。除了节标题之外,这会使 tableView 变暗。我尝试从viewWillAppear: 中调用[tableView bringSubviewToFront:self.blackOverlay],但我得到了相同的行为。

我当前的解决方法是在覆盖层存在时为 tableView 部分标题返回 nil,但这会在部分标题之前所在的重叠 tableView 中留下空白间隙。

如何确保 tableView 部分标题永远不会绘制在 blackOverlay 之上?或者,是否可以在不是 tableView 子视图的 UITableViewController 子类中在 tableView 前面创建一个视图?

【问题讨论】:

【参考方案1】:

首先,您的功能应该稍作调整。如果您要返回的对象是 alloc'd 但不是 autorelease'd,那么您的方法名称应该表明这一点(即 newBlackOverlay)。其次,您的方法正在修改一个没有给它的tableView 对象,因此它与其他组件的交互并不明显(参见Law of Demeter)。

问题是您将此黑色叠加层作为表格视图的子级。您应该将它插入到表视图的同一级别,即:

UIView(设置为视图控制器的视图) | +-UITableView | +-UIView(你的新黑色覆盖)

您可以在 Interface Builder 中创建它,并根据需要设置 backgroundColor/alpha 属性。在您的视图控制器中创建一个新的UIView@property 并将其设置为您的新UIView。然后,您可以更改覆盖的 alpha 值和/或将其完全隐藏在您的回调函数中,以便用户开始/结束搜索任务。

我有一个 UITableView,它的数据有 部分。我在 tableView 的顶部,当它变暗时 搜索

FWIW,如果您不知道,您可以使用 Apple 在 iPhone OS 3.x 中引入的新 UISearchDisplayController 类相当轻松地构建搜索屏幕。可能会省去你重新发明***的麻烦,在这里。

【讨论】:

我应该指定 blackOverlay 实际上是一个延迟加载的只读属性,所以对象实际上是在管理它的内存。感谢您将我介绍给 UISearchDisplayController。我不知道它的存在,实际上我似乎在重新发明***! 仅供参考,如果给定一个 TableViewController 作为它的 contentsController,那么 UISearchDisplayController 也会直接在 tableView 上绘制。【参考方案2】:

我通过创建一个根视图控制器并将我的表视图作为该控制器的子视图解决了这个问题:

- (void)viewDidLoad 
    [super viewDidLoad];

    // Create the root view to hold the table view and an overlay
    UIView *root = [[UIView alloc] initWithFrame:self.navigationController.view.frame];
    root.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    root.autoresizesSubviews = YES;
    self.view = root;

    // Setup the table view
    UITableView *newTableView = [[UITableView alloc] initWithFrame:self.navigationController.view.frame style:UITableViewStylePlain];
    newTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.tableView = newTableView;
    [newTableView release];
    [root addSubview:self.tableView];

    [root release];

然后我可以在 tableView 顶部使用带有搜索栏的UISearchDisplayController,而不会出现问题。

【讨论】:

以上是关于UITableView 部分标题在前子视图上方绘制的主要内容,如果未能解决你的问题,请参考以下文章

UIViewController 根视图中的 UITableView 显示

禁用 UITableView 浮动部分标题点击?

使用自定义单元格反转 UITableView

带部分的可折叠 UITableView

在 UITableView 上方调整 UIView 的大小

UISearchBar 上方的 UITableView 部分