You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swift中实现类Google Maps地点描述的自定义分段视图?

实现Google Maps风格的分段导航+TableView分区跳转

以下是实现需求的具体方案,全程在同一视图内完成分段标签点击到对应TableView分区的跳转:

一、添加顶部分段导航控件

可以直接用系统的UISegmentedControl,也可以自定义标签栏匹配设计风格,这里以系统控件为例:

// 初始化分段控件,设置对应标签
let segmentControl = UISegmentedControl(items: ["概览", "详情"])
segmentControl.selectedSegmentIndex = 0
// 绑定点击事件
segmentControl.addTarget(self, action: #selector(segmentTapped(_:)), for: .valueChanged)
// 添加到视图并设置约束
view.addSubview(segmentControl)
segmentControl.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    segmentControl.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
    segmentControl.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
    segmentControl.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16)
])

二、配置TableView多分区结构

先定义分区枚举统一管理分段标签与TableView分区的对应关系:

enum PlaceSection: Int, CaseIterable {
    case overview, description
    
    var title: String {
        switch self {
        case .overview: return "概览"
        case .description: return "详情"
        }
    }
}

再实现TableView的核心数据源方法:

// 返回分区数量
func numberOfSections(in tableView: UITableView) -> Int {
    return PlaceSection.allCases.count
}

// 设置分区标题(可选,按需决定是否显示)
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return PlaceSection(rawValue: section)?.title
}

// 返回每个分区的行数
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch PlaceSection(rawValue: section)! {
    case .overview: return 3 // 替换为实际业务行数
    case .description: return 5
    }
}

// 配置每个cell的内容
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ContentCell", for: indexPath)
    switch PlaceSection(rawValue: indexPath.section)! {
    case .overview:
        cell.textLabel?.text = "概览模块内容行 \(indexPath.row + 1)"
    case .description:
        cell.textLabel?.text = "详情模块内容行 \(indexPath.row + 1)"
    }
    return cell
}

三、实现分段标签点击跳转逻辑

响应分段控件的点击事件,让TableView滚动到目标分区顶部:

@objc private func segmentTapped(_ sender: UISegmentedControl) {
    guard let targetSection = PlaceSection(rawValue: sender.selectedSegmentIndex) else { return }
    let targetIndexPath = IndexPath(row: 0, section: targetSection.rawValue)
    // 带动画滚动到目标位置,无需动画可设为false
    tableView.scrollToRow(at: targetIndexPath, at: .top, animated: true)
}

四、可选:滚动TableView时同步更新选中标签

如果需要滚动到某个分区时自动切换分段控件的选中状态,监听滚动事件即可:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    guard let firstVisibleIndexPath = tableView.indexPathsForVisibleRows?.first else { return }
    let currentSection = PlaceSection(rawValue: firstVisibleIndexPath.section)!
    if segmentControl.selectedSegmentIndex != currentSection.rawValue {
        // 关闭动画避免滚动时频繁触发UI变化
        UIView.performWithoutAnimation {
            segmentControl.selectedSegmentIndex = currentSection.rawValue
        }
    }
}

额外提示

  • 若分区有自定义header且需滚动到header顶部,可使用tableView.scrollRectToVisible(_:animated:)计算header的frame实现
  • 自定义分段标签栏时,可使用UIButton组合,实现下划线、选中态颜色等更灵活的样式
  • 确保TableView的contentInset设置正确,避免内容被顶部分段控件遮挡

内容的提问来源于stack exchange,提问作者Pritesh Kankaria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:50:27