Swift UITableView如何让第1组footer固定在组底部不浮动
我懂你遇到的这个问题——用viewForFooterInSection做的Section Footer滚动时到处飘,完全不是你想要的“钉在第1组底部”的效果。其实这个问题大多和UITableView的样式有关,给你两个可行的解决方案,按需选就行:
方案一:切换UITableView为Grouped样式(最简单)
如果你的界面设计允许,直接把TableView的样式改成Grouped就能解决问题。因为Grouped样式下,每个Section的Footer默认就会牢牢固定在该Section内容的底部,不会随着滚动被顶来顶去。
设置方法:
- Storyboard/XIB创建:选中TableView,在右侧属性面板里找到「Style」,从「Plain」改成「Grouped」;
- 代码创建:初始化TableView时指定样式:
let tableView = UITableView(frame: view.bounds, style: .grouped)
这个方案零成本,优先考虑它!
方案二:自定义固定Footer(无法改样式时用)
如果因为界面需求不能切换到Grouped样式,那我们可以手动创建一个Footer视图,把它直接加到TableView上,通过计算Section的位置来固定它。
步骤1:提前创建好Footer视图
在你的ViewController里声明并初始化这个Footer:
private let stickyFooterView: UILabel = { let label = UILabel() label.text = "A sticky footer here..." label.font = .systemFont(ofSize: 16) label.textColor = .gray label.backgroundColor = .clear label.textAlignment = .left label.translatesAutoresizingMaskIntoConstraints = false return label }()
步骤2:把Footer加到TableView上
在viewDidLoad里添加视图并设置基础约束:
override func viewDidLoad() { super.viewDidLoad() // 先做好你的TableView基础配置(注册Cell、设置数据源代理等) tableView.addSubview(stickyFooterView) // 设置左右和高度约束,Y轴约束后面动态调整 NSLayoutConstraint.activate([ stickyFooterView.leftAnchor.constraint(equalTo: tableView.leftAnchor, constant: 20), stickyFooterView.rightAnchor.constraint(equalTo: tableView.rightAnchor), stickyFooterView.heightAnchor.constraint(equalToConstant: 40) // 高度对应你之前的top=10+bottom约束总和 ]) }
步骤3:动态计算并更新Footer位置
重写viewDidLayoutSubviews方法,实时获取第1组的位置,把Footer钉在它的底部:
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // 注意:这里的section索引是1,要和你代码里的判断一致(UITableView的section从0开始计数) guard let sectionRect = tableView.rect(forSection: 1) else { return } // 计算Footer应该在的Y坐标:第1组的底部位置 let targetFooterY = sectionRect.origin.y + sectionRect.size.height // 更新Footer的垂直位置 stickyFooterView.topAnchor.constraint(equalTo: tableView.topAnchor, constant: targetFooterY).isActive = true // 可选:如果第1组完全滚出屏幕,就隐藏Footer let visibleTableArea = tableView.bounds if sectionRect.maxY < visibleTableArea.minY { stickyFooterView.isHidden = true } else { stickyFooterView.isHidden = false } }
步骤4:关闭系统的第1组Footer
最后,记得把第1组的系统Footer高度设为0,避免出现重复:
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { // 第1组用我们自定义的Footer,系统的就留空 return section == 1 ? 0 : UITableView.automaticDimension }
小提醒:
确认好你的「第1组」对应的section索引!UITableView的section是从0开始计数的,如果你的第一个组就是要加Footer的组,那代码里的section == 1要改成section == 0,别搞混了哦。
内容的提问来源于stack exchange,提问作者Aldo Sugiarto
相关产品推荐
相关产品推荐

