使用 insets 向 UITableView 添加视图,有啥问题吗?

Posted

技术标签:

【中文标题】使用 insets 向 UITableView 添加视图,有啥问题吗?【英文标题】:Add view to UITableView using insets, does it have any problem?使用 insets 向 UITableView 添加视图,有什么问题吗? 【发布时间】:2019-01-22 08:10:07 【问题描述】:

我在UITableView(或UICollextionView)的底部添加一个视图,但不是作为单元格或页脚,而只是将其添加到表格视图本身(因此,添加到UIScrollView)然后播放与滚动的contentInset。这样做的目的是将视图保持在表格内容的底部,而不是在内容的末尾。这样,如果内容短于表格的边界,则视图可见(左图),但如果内容较高,则视图显示在内容的末尾(右图)。

这是代码的摘录:

let yCoord = collectionView.contentSize.height >= view.frame.height - viewHeight
    ? collectionView.contentSize.height
    : view.frame.height - viewHeight

let bottomView = UIView(frame: CGRect(x: 0, y: yCoord, width: collectionView.contentSize.width, height: viewHeight))

collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: viewHeight, right: 0)
collectionView.addSubview(bottomView)

我想知道这种方法是否会以任何方式被认为是有害的,例如,AL 问题、旋转、重新加载表......我没有发现任何问题,实际上这是一种非常相似的方法ios 6 之前的 pull-to-refresh 功能,但我宁愿在将其投入生产之前确定它。

如果这可以被认为是一个问题,除了添加新单元格之外,您还提出了哪种解决方案?

【问题讨论】:

如何计算 yCoord ?为什么不使用这些计算来决定是否应该将视图添加到我们的表格视图上方或作为 tableViewFooterView ?在这里,即使内容比表格的边界短,用户也可以稍微滚动表格视图(如果您将 alwaysBounceVertical 设置为 false,但这不是本机行为) 大家好。我刚刚发布了我的代码的摘录,但它有效。我不是要一个可行的解决方案,而是一个更好的解决方案。我的意思是,我认为检查内容偏移的坐标等比那样做更复杂,恕我直言。无论如何,我添加了完整的代码。 【参考方案1】:

如果您想要上述功能,您必须在 scrollView 中获取 tableView 和底部视图,并使用内容观察器根据内容为 tableView 提供动态高度,并将底部视图保持在滚动视图的底部,并将 tableView 作为从上到下的视图和给出大于或等于归属的值。

希望它会起作用。

【讨论】:

【参考方案2】:

试试下面的代码。使您的页脚视图颜色清晰,并在您的页脚视图中放置另一个视图,并具有底部、左侧、右侧和高度限制

@IBOutlet weak var footerView: UIView!

   //MARK:- View Controller life cycle method
override func viewDidLoad() 
    super.viewDidLoad()
    yourTableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)


override func viewWillDisappear(_ animated: Bool) 
    super.viewWillDisappear(animated)
    yourTableView.removeObserver(self, forKeyPath: "contentSize")


override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 
    if(keyPath == "contentSize")
            let contentHeight: CGFloat = yourTableView.contentSize.height
            let tableHeight = yourTableView.frame.size.height

            if contentHeight < tableHeight 
                footerView.frame = CGRect(x: footerView.frame.origin.x, y: footerView.frame.origin.y, width: footerView.frame.size.width, height: CGFloat(tableHeight - contentHeight + 44.0))
                // 44.0 is your initial footer height which you put in xib

             else 
                footerView.frame = CGRect(x: footerView.frame.origin.x, y: footerView.frame.origin.y, width: footerView.frame.size.width, height: 44.0)
                 // 44.0 is your initial footer height which you put in xib
            
    

【讨论】:

【参考方案3】:

我更愿意创建一个 UIView 子类来包装表格视图和浮动页脚视图。我避免修改完全由框架管理的类的视图层次结构,并且使用子类很容易在其他地方使用这种布局。使用滚动视图委托scrollViewDidScroll 事件,它会在用户每次滚动时更新页脚视图框架。顺便说一句,我肯定会使用约束来放置我的页脚视图,而不是使用可能会更改的框架。

您的实施中有什么有害的吗?

您没有提及添加代码的位置。如果它是 viewDidLoad,那么如果您使用自动布局并且视图的框架由于旋转或特征集合更改而发生更改,那么您将遇到麻烦。此外,如果您的内容不是静态的,则调用 reload data 将使 table view 的内容大小无效,这也会创建错位的页脚视图。

我们应该把这些代码行放在哪里?

我们是否应该 KVO 观察表格视图框架及其内容以在每次更改时更新页脚视图的框架?

当然不是! Apple 已经提供了我们需要的所有活动。至少,将这些行放在viewDidLayoutLayouts 中,并确保不要多次添加页脚视图。每次布局控制器的视图时都会调用viewDidLayoutLayouts

【讨论】:

我在显示最后一个单元格时添加它。我已经更新了问题。

以上是关于使用 insets 向 UITableView 添加视图,有啥问题吗?的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 的子视图永远不会出现

UITableViewCell 放置事件

UITableView 分隔符在 iOS7 中显示不正确

如何使用 .yaml 文件向 AWS Lambda 函数添​​加策略?

4.13

使用 numpy.npv 函数的输出向数据框中添加一列