如何在Swift中创建Horizontal UITableView?不使用第三方库
不用第三方库实现Swift水平UITableView
嘿,刚好做过这个需求,完全不用第三方库就能搞定!其实UITableView本身就是UIScrollView的子类,天生支持滚动方向调整,咱们只需要做几个关键配置就行,一步步来:
1. 初始化并配置UITableView
首先在你的ViewController里创建UITableView,设置好数据源、代理,核心是通过旋转变换把垂直的TableView改成水平的:
class HorizontalTableVC: UIViewController, UITableViewDataSource, UITableViewDelegate { private var tableView: UITableView! // 模拟数据源 private let items = ["苹果", "香蕉", "橙子", "葡萄", "西瓜", "芒果"] override func viewDidLoad() { super.viewDidLoad() setupHorizontalTable() } private func setupHorizontalTable() { tableView = UITableView(frame: view.bounds) tableView.dataSource = self tableView.delegate = self // 注册默认cell,自定义cell同理 tableView.register(UITableViewCell.self, forCellReuseIdentifier: "HorizontalCell") // 关键操作:将TableView逆时针旋转90度,实现水平滚动 tableView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2) // 隐藏底部多余分隔线 tableView.tableFooterView = UIView() view.addSubview(tableView) // 如果用AutoLayout替代frame: tableView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) } }
2. 配置Cell的布局与反向旋转
因为TableView整体旋转了,所以Cell也得顺时针旋转回来,这样内容才是正的,同时要调整Cell的尺寸适配水平显示:
// MARK: - UITableView DataSource func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 这里的行数对应水平方向的单元格数量 return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "HorizontalCell", for: indexPath) cell.textLabel?.text = items[indexPath.row] cell.textLabel?.textAlignment = .center // 关键:将Cell顺时针旋转90度,抵消TableView的旋转 cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 2) // 确保contentView跟随Cell尺寸变化 cell.contentView.frame = cell.bounds cell.contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] return cell } // MARK: - UITableView Delegate func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { // 这里设置的"行高",旋转后就是水平单元格的宽度,按需调整 return 120 } // 处理单元格点击(可选) func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print("选中了:\(items[indexPath.row])") tableView.deselectRow(at: indexPath, animated: true) }
注意事项
- 如果用自定义Cell,要确保子视图的AutoLayout或autoresizingMask设置正确,避免旋转后布局错乱;
- 若需要添加表头/表尾,记得对headerView/footerView也执行同样的旋转操作;
- 旋转后滚动指示器方向会跟着变化,如果你觉得别扭,可以自定义指示器样式,或者接受默认效果(大部分场景下没问题)。
替代方案:无旋转实现
如果你不想用旋转,也可以通过调整TableView的布局参数实现:把TableView的高度设为单元格的期望宽度,然后手动计算contentSize.width等于所有单元格的总宽度,但这种方法需要处理更多的布局细节,不如旋转方案成熟顺手,所以更推荐前面的旋转实现。
内容的提问来源于stack exchange,提问作者jo jo
相关产品推荐
相关产品推荐

