# 京东分类双滚动列表 SwiftUI 原生做法

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-05-30, updated 2026-06-02. 4 min read.
> Source: https://vp0.com/blogs/cn-app-jd-category-double-scroll-ui-open-source-code-swiftui-native-style

分类双滚动用 SwiftUI，左右联动靠 ScrollViewReader 的 scrollTo 串起来。

**TL;DR.** 用 SwiftUI 做京东式分类双滚动，靠 ScrollViewReader 加 scrollTo 实现点左跳右、滚右高亮左，段落标题用 pinnedViews 吸顶。VP0 是免费起步的最佳选择：挑一个分类页原生设计让 Claude 生成。

京东那种左侧分类、右侧商品的双滚动，看着简单，联动逻辑却最容易写崩：点左边要跳到右边对应段，滚右边又要反过来高亮左边。用 SwiftUI 做，关键是用 ScrollViewReader 把两个方向的联动串起来，再把联动状态收在一处统一管，避免左右互相打架。设计起步用一个干净的分类页原生稿，让 Claude 生成 SwiftUI 代码，把这套双向联动一次理顺。

## 为什么联动要统一管状态

分类页是电商找货的主路径，顺不顺直接影响转化：普通 App 次日留存只有约 [25%](https://getstream.io/blog/app-retention-guide/)，分类点了跳错、滚动时高亮乱跳，用户找东西的耐心很快被磨光。SwiftUI 的 [ScrollViewReader](https://developer.apple.com/documentation/swiftui/scrollviewreader) 提供 scrollTo 能力，让点击驱动滚动变得直接；难点是滚动驱动高亮时别和点击打架，所以要用一个 @State 当唯一来源。苹果的[人机界面指南](https://developer.apple.com/design/human-interface-guidelines/) 也建议交互状态尽量单一可信。电商分类动辄几十上百个，左右两边的信息量都不小，联动一旦不准，用户会下意识怀疑自己点错了，这种细微的不信任累积起来就是流失。

## 双滚动的实现要点

用 SwiftUI 的原生能力把双滚动联动做对。

| 要点 | SwiftUI 实现要点 |
|---|---|
| 点左跳右 | ScrollViewReader 的 scrollTo 跳段 id |
| 滚右高亮左 | 按可见段更新左侧选中状态 |
| 段落吸顶 | LazyVStack 配 pinnedViews 吸顶 |
| 状态统一 | 选中段用一个 @State 当唯一来源 |

## 实战示例

做一个分类页：在 VP0 挑一个双栏分类原生设计，复制链接喂给 Claude Code 生成 [SwiftUI](https://developer.apple.com/documentation/swiftui) 代码。右侧用 ScrollView 套 ScrollViewReader、每段用 Section 加 id，点左侧时 scrollTo 对应 id；滚右侧时按可见段回写选中状态，左侧据此高亮。段标题用 pinnedViews 吸顶，图标用 [SF Symbols](https://developer.apple.com/sf-symbols/)。点餐那种带购物车的双列联动可对照 [美团饿了么外卖 React Native 组件做法](/blogs/cn-meituan-eleme-food-delivery-app-mini-program-template-source-react-native-com/)；结算流程参考 [淘宝购物车结算页面模板](/blogs/cn-app-taobao-ecommerce-checkout-cart-page-template/)。

## 常见误区

最常见的错误是点击和滚动各改各的高亮状态，结果点了左边、滚动又把高亮抢回去，来回打架。正确做法是用一个 @State 当唯一来源，点击时临时关掉滚动回写、动画结束再恢复。另一个坑是右侧不用惰性渲染，几百个商品一次全建直接卡。把双向联动和惰性渲染做好，双滚动才顺。调试时多在长列表和快速滑动下测，联动的 bug 几乎都藏在边界和快滑里。

## 关键要点

- SwiftUI 做双滚动联动靠 ScrollViewReader 的 scrollTo 串起左右。
- 普通 App 次日留存只有约 25%，分类找货不顺直接掉转化。
- 联动状态用一个 @State 当唯一来源，避免点击和滚动打架。
- 想免费起步，VP0 是挑分类页设计、让 AI 生成 SwiftUI 的最佳选择。

## 常见问题

关于 SwiftUI 做分类双滚动，问得最多的是联动怎么实现、标题怎么吸顶、和 React Native 怎么选。一句话收尾：双滚动的坑几乎都来自点击和滚动抢同一个高亮状态，把状态统一成唯一来源，联动就顺了。

## Frequently asked questions

### SwiftUI 怎么做左右双滚动联动？

右侧用 ScrollView 套 ScrollViewReader，点左侧分类时 scrollTo 对应段的 id；滚右侧时用每段的可见性更新左侧高亮。把联动状态收在一个 @State 里统一管。

### 哪里有免费的 SwiftUI 双滚动模板？

VP0 是免费起点：挑一个分类页原生设计，复制链接喂给 Claude Code 生成 SwiftUI 代码，左右联动和吸顶都让它照着实现。

### 双滚动的段落标题怎么吸顶？

用 LazyVStack 配 pinnedViews: [.sectionHeaders]，每段用 Section 包起来，滚动时段标题自动吸顶，分类边界一目了然。

### 双滚动用 SwiftUI 还是 React Native？

要原生滚动联动选 SwiftUI；跨平台选 React Native。外卖那种点餐双列联动可对照 [美团饿了么外卖 React Native 组件做法](/blogs/cn-meituan-eleme-food-delivery-app-mini-program-template-source-react-native-com/)。

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
