【问题标题】:UITableView section header disappears if I insert or delete rows如果我插入或删除行,UITableView 部分标题会消失
【发布时间】:2014-06-18 22:47:38
【问题描述】:

我有一个UITableView,有 4 个部分。其中三个部分有一个标题视图。

标题视图是UITableViewCell,我将其作为viewForHeaderInSection: 委托中的普通单元格出列。

如果我从任何部分插入或删除一行,其他 tableview 标题单元格就会消失。

我假设这与单元格重用有关,但是单元格最初都出现在屏幕上(所有三个标题同时出现在屏幕上)。

我尝试在插入或删除后重新加载其他部分,但这没有帮助。

这里有一些代码:

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    switch (section) {

        case kSectionCardInformation:
        case kSectionContactInformation:
        case kSectionTags: {

            static NSString *CellIdentifier = @"EditContactHeaderCell";
            EditContactHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
            return cell;
        }

        default:
            return nil;
    }
}

这里是我删除相关部分中的行的地方:

- (void)deleteTag:(CDTag *)tag {

    [self.tableView beginUpdates];

    NSMutableArray *objects = [self.sections objectAtIndex:kSectionTags];
    if ([objects containsObject:tag]) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[objects indexOfObject:tag] inSection:kSectionTags];
        [objects removeObject:tag];

        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationMiddle];

        [self.contact deleteTag:tag];
    }

    [self.tableView endUpdates];
}

任何帮助,不胜感激。

【问题讨论】:

  • 我发现使用不是 UITableViewCell 子类的视图可以解决这个问题。但我不明白为什么。

标签: ios objective-c uitableview


【解决方案1】:

不要返回您的 FooterCell 或 HeaderCell ,或您的可重用标识符。返回reuseIdentifier.contentView。对我来说是:返回 headerCell!.contentView。 func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 让 headerCell = tableView.dequeueReusableHeaderFooterView(withIdentifier:"CustomViewHeaderView") 为! CustomViewHeaderView

return headerCell.contentView

}

【讨论】:

    【解决方案2】:

    对于 Swift 4,5

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    
        let containerView = UIView()
        guard let headerCell = tableView.dequeueReusableCell(withIdentifier: "MyHeaderView") as? MyHeaderView else { fatalError(" Failed to load MyHeaderView") }
        containerView.addSubview(headerCell)
        return containerView
    }
    

    【讨论】:

      【解决方案3】:

      返回cellcontentView 对我来说效果很好。无需将单元格包裹在 UIView 中。

      func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
          let headerCell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell")
          return cell.contentView
      }
      

      【讨论】:

      • 工作完美并调整大小(这是我尝试执行“将单元格放入视图”解决方案的问题)
      • 在尝试了几个答案后,这个是最直接的,但它假设您的部分标题中没有任何按钮
      • @craft 我正在使用相同的方法,但我的标题单元格中有按钮,当删除所有行并再次点击按钮以添加更多行时,该按钮会消失。
      • @iPhone7 - 啊,是的,我可能弄错了。你是说即使有按钮它仍然有效?似乎应该,再次查看此答案。如果是这样,我会删除我的评论。谢谢
      • @craft 不,我是说当有按钮时它不起作用。诊断的原因是,由于 TapGesture 关闭键盘干扰了功能。在我的情况下,当点击它的按钮时,完整的标题视图会消失。希望我能向你阐明我的观点吗?
      【解决方案4】:

      正确 解决此问题的方法是使用 UITableViewHeaderFooterView 而不是使用 UITableViewCell 作为标题部分。就像@Francois Nadeau 回答的那样。

      有关如何将 UITableViewHeaderFooterView 用于标题部分的更多详细信息,请参阅此答案:https://stackoverflow.com/a/36931047

      【讨论】:

        【解决方案5】:

        添加评论,因为我有同样的问题......问题是我也使用 UITableViewCell 作为标题而不是使用 UITableViewHeaderFooterView。

        解决问题:

        1. 创建一个 nib 文件并在其中创建自定义标题,而不是在情节提要的 UITableView 中。
        2. 将其链接到您的自定义 UITableViewHeaderFooterView 类
        3. 在你的 viewDidLoad 函数中注册这个 nib

          override func viewDidLoad() {
              self.tableView.rowHeight = UITableViewAutomaticDimension
          
              self.tableView.register(UINib(nibName: "NibFileName", bundle: nil), forHeaderFooterViewReuseIdentifier: "CustomViewHeaderView")
          }
          
        4. 从 viewForHeaderInSection 函数中取出可重用的 HeaderFooterView:

          func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
              let cell = tableView.dequeueReusableHeaderFooterView(withIdentifier:"CustomViewHeaderView") as! CustomViewHeaderView
          
              return cell
          }
          

        这修复了我消失的页眉。我希望它可以帮助其他人。

        【讨论】:

        • 这绝对是一种更清洁的解决方案,使用预期的类而不是将单元格包装到视图中。
        • 完美,它也对我有用。它应该被标记为正确答案:)
        • 哇,你为我节省了这么多时间——不知道我是否会想到这一点!谢谢!
        【解决方案6】:

        我不知道你为什么要使用 tableview 单元格作为标题,但我的假设是

        你错过了break语句

        - (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
        
            switch (section) {
        
                case kSectionCardInformation:
                    break;
                case kSectionContactInformation:
                    break;
                case kSectionTags: {
        
                    static NSString *CellIdentifier = @"EditContactHeaderCell";
                    EditContactHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
                    return cell;
                }
        
                default:
                    return nil;
            }
        }
        

        在返回单元格之前检查nil 条件,如果为 nil 则创建单元格。

                    static NSString *CellIdentifier = @"EditContactHeaderCell";
                    EditContactHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        
                    return cell ?: createdCellNewly;
        

        更新:

        然后检查您的 numberOfSectionsInTableView:(UITableView *)tableView 方法是否返回正确的计数。

            - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
                 // returning count is correct?
            }
        

        检查并设置 tableview 的委托和数据源。

        【讨论】:

        • 我不需要 break 语句 - 这三个 case 语句都适用于创建单元格。事实上,在我插入或删除一行后,该函数不会再次被调用(仅当标题从屏幕上掉下来并重新出现时)。
        • 维杰。感谢您的帮助,但以上所有内容均已正确涵盖。
        【解决方案7】:

        只需将您的 UITableViewCell 包装到 UIView 中即可。

        - (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
        
        switch (section) {
        
            case kSectionCardInformation:
            case kSectionContactInformation:
            case kSectionTags: {
        
                static NSString *CellIdentifier = @"EditContactHeaderCell";
                EditContactHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
                UIView * view = [[[UIView alloc] init] autorelease];
                [view addSubview:cell];
                //setup the view's frame: fixed, autolayout, ...
                return view;
            }
        
            default:
                return nil;
        }
        

        }

        【讨论】:

        • 这行得通。知道为什么我们需要将其包装在 UIView 中吗?
        • 我猜表格视图探索了它的子视图,如果标题视图是一个单元格,它会以某种方式被处理为一个单元格。
        • 有趣。我在自定义 UIView 子类时遇到了同样的问题,所以它可能使用带有 kindOf: 的 if 语句而不是 memberOf:
        猜你喜欢
        • 1970-01-01
        • 2015-02-18
        • 2017-07-06
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多