刷新 UITableView 而不刷新节标题

Posted

技术标签:

【中文标题】刷新 UITableView 而不刷新节标题【英文标题】:Refresh UITableView without refresh section header 【发布时间】:2019-08-03 05:15:42 【问题描述】:

我有 UITableview 和节标题。当section header粘在View的顶部时,我想刷新table view的数据源,但是不希望section header被刷新。由于部分标题有几个按钮,我想保持不变

只能刷新 UITableView 数据源吗?或者我必须把节标题放在 UITableView 之外?

【问题讨论】:

Reload section without reloading section header的可能重复 【参考方案1】:

Table View Delegate 包含滚动视图方法,因此您可以按照以下方式执行逻辑

func scrollViewDidScroll(_ scrollView: UIScrollView) 
     if scrollView.contentOffset.y == 0 
         tableView.reloadData()
     

【讨论】:

我不想重新加载节标题。 table view.reloadData 会更新所有内容。我只需要更新该部分中的所有单元格。 哦,好的,抱歉。而不是使用tableView.reloadSections(IndexSet, with: UITableView.RowAnimation) 而不是tableView.reloadData() 它完全按照我想要的方式工作,只有当节标题不粘在顶部时。当它粘在顶部时,reloadSections 会使部分标题中的按钮弹跳一点。无论如何,我猜部分标题仍在刷新。【参考方案2】:

我尝试使用table.reloadSections(IndexSet(integer: 0), with: UITableView.RowAnimation.none) 重新加载第一部分。

这是录屏链接bouncey section header content

【讨论】:

【参考方案3】:

我发现解决方案是从 tableview 部分标题中删除内容,而部分标题粘在顶部。而是将其添加到视图中。

然后我们可以刷新section或者tableview。如果我们向下滚动,则将标题放回部分标题容器。

删除节标题,当标题内有按钮时

    @objc func refreshSection()
    if sectionHeaderStickyTop == true 
        guard let header = sectionHeaderContainer.subviews.first else 
            return
        

        sectionHeaderStickyTop = false

        header.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(header)

        let guide = view.safeAreaLayoutGuide

        header.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
        header.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
        header.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
        header.heightAnchor.constraint(equalToConstant: header.bounds.size.height).isActive = true
    

    table.reloadSections(IndexSet(integer: 0), with: UITableView.RowAnimation.none)

把标题放回节标题,如果标题已经 删除

    func scrollViewDidScroll(_ scrollView: UIScrollView) 
    guard let tableView = scrollView as? UITableView else 
        return
    

    let header = sectionHeader
    dummyButton.setTitle("\(Int.random(in: 1...100))", for: UIControl.State.normal)
    dummyButton.translatesAutoresizingMaskIntoConstraints = false
    dummyButton.addTarget(self, action: #selector(refreshSection), for: UIControl.Event.touchUpInside)

    let headerViewHeight = table.tableHeaderView?.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height ?? 0


    if scrollView.contentOffset.y >= headerViewHeight 
        addToHeader(header: header, addonView: dummyButton, height: 44, width: 80)
    else
        if sectionHeaderStickyTop == false 
            sectionHeaderStickyTop = true
            sectionHeader.translatesAutoresizingMaskIntoConstraints = true
            header.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleTopMargin, .flexibleBottomMargin, .flexibleLeftMargin, .flexibleRightMargin]
            header.frame = CGRect(x: 0, y: 0, width: header.bounds.width, height: header.bounds.height)
            sectionHeaderContainer.addSubview(sectionHeader)
        
        dummyButton.removeFromSuperview()
    
    tableView.setNeedsLayout()

【讨论】:

以上是关于刷新 UITableView 而不刷新节标题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UITableView 中刷新单节标题的文本

NSFetchedResultsController 刷新 UITableView 条目而不重新加载口吃

更改 tableview 的 inset 时 UITableView 中的节标题

UITableView 刷新不滚动

如何刷新 UITableView 数据?

UITableView - 带有背景图像的 UIRefreshControl