Install
$ agentstack add skill-mythkiven-figma-ios-codegen-figma-ios-selection-interaction ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Figma 选择交互逻辑生成
职责范围
- ✅ 从
figma-ios-preload-data数据包(design.json)自动识别选择交互模式(单选/多选/Toggle) - ✅ 生成选中态变化逻辑(更新数据模型、刷新 UI)
- ✅ 生成
didSelectItemAt(列表统一 UICollectionView;不用UITableView/didSelectRowAt) - ✅ 生成单个按钮 Toggle 逻辑
- ✅ 集成 RxSwift 交互模式(按
host.interaction;默认也可 target-action,见 rxswift skill) - ✅ 保持数据模型与 UI 同步
- ❌ 不处理业务逻辑(网络请求、页面跳转等,留 TODO 注释)
- ❌ 不处理动画效果(由其他 Skill 负责)
- ❌ 不从 Figma MCP / REST 再拉数据;视觉差异读
design.json(或已由figma-ios-component-state-recognition提取的状态) - ❌ 不替代
figma-ios-component-state-recognition(外观 /updateAppearance)与figma-ios-uicollectionview-codegen(CV 骨架)
适用场景
| 场景 | Figma 特征 | 生成代码 | |------|-----------|---------| | ListView 单选 | 多个同类节点,只有 1 个选中 | didSelectItemAt + 单选互斥逻辑 | | ListView 多选 | 多个同类节点,多个选中 | didSelectItemAt + Toggle 逻辑 | | 单个按钮 Toggle | 单个节点有选中态 | RxSwift tap + Toggle 逻辑 | | SegmentedControl | 多个并列按钮,1 个选中 | 按钮组 + 单选互斥逻辑 |
识别规则
规则 1:ListView 单选模式
触发条件(必须全部满足):
def is_single_selection_listview(figma_nodes):
"""
判断是否为单选 ListView
"""
# 1. 节点数量 ≥ 2
if len(figma_nodes) 本仓列表**一律** UICollectionView。短选项(性别 / 筛选项)也用 CV,不要生成 `UITableView`。
**数据模型:**
```swift
struct GenderItem {
let id: String
let title: String
var isSelected: Bool
}
private var genders: [GenderItem] = [
GenderItem(id: "1", title: "不限", isSelected: true),
GenderItem(id: "2", title: "男生", isSelected: false),
GenderItem(id: "3", title: "女生", isSelected: false)
]
生成交互逻辑:
// MARK: - UICollectionViewDelegate
extension GenderSelectionCell: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// ========== 单选模式:取消所有选中,只选中当前项 ==========
for i in 0.. 1
Step 2:统计选中节点数量
def count_selected_nodes(figma_nodes):
"""统计有多少个节点处于选中态(读 design.json)。"""
return sum(1 for node in figma_nodes if is_node_selected(node, peers=figma_nodes))
def is_node_selected(node, peers=None):
"""
判断单个节点是否更像「选中态」。读 design.json,不读 Tailwind / MCP。
启发式(可与 component-state-recognition 对齐):
- fills/strokes 的 rgba alpha 更高、或颜色与同伴不同
- font.weight 更粗(如 ≥500)
- 名称含 选中/selected/active
"""
name = (node.get("name") or "").lower()
if any(k in name for k in ("选中", "selected", "active")):
return True
font = node.get("font") or {}
if (font.get("weight") or 0) >= 500 and peers:
weights = [(p.get("font") or {}).get("weight") or 400 for p in peers]
if font.get("weight") == max(weights) and len(set(weights)) > 1:
return True
fills = node.get("fills") or []
for f in fills:
color = f.get("color") or ""
# alpha 段:rgba(r,g,b,a) 中 a 明显大于同伴常见「淡选中底」
if "rgba(" in color and color.rstrip(")").split(",")[-1].strip() not in ("0", "0.0", "1", "1.0"):
# 有半透明主题底时倾向选中;精确对比交给 peers 差分
if peers and has_selection_state(peers):
return True
return False
> 具体主题色以当前稿 fills[].color 为准,不要写死某业务色值;上表只示意差分思路。
Step 3:判断交互模式
def detect_interaction_mode(figma_nodes):
"""
综合判断交互模式
"""
# 1. 检查是否有选中态
if not has_selection_state(figma_nodes):
return None
# 2. 统计选中节点数量
selected_count = count_selected_nodes(figma_nodes)
# 3. 判断是否为列表
is_list = is_listview(figma_nodes)
# 4. 返回交互模式
if is_list:
if selected_count == 1:
return 'single_selection' # ListView 单选
elif selected_count >= 2:
return 'multiple_selection' # ListView 多选
else:
return None # 没有默认选中(需要手动处理)
else:
# 单个节点
if len(figma_nodes) == 1:
return 'toggle' # 单个按钮 Toggle
return None
与其他 Skills 的协作
[1] figma-ios-component-state-recognition
↓ 识别选中/未选中视觉特征 → updateAppearance() + isSelected 模型字段
[2] figma-ios-listview-recognition
↓ 判定 UICollectionView(禁 UITableView)→ audit / _layout_hint.list
[2b] figma-ios-uicollectionview-codegen(list 命中后必须加载)
↓ CV / Cell / DataSource 骨架 + Mock
[3] figma-ios-selection-interaction(本 Skill)
↓ 单选/多选/Toggle → didSelectItemAt / toggle 逻辑(不写 TableView)
[4] figma-ios-rxswift-interaction-pattern
↓ 按 host.interaction 绑点击(按钮 Toggle 等)
生成顺序:
figma-ios-component-state-recognition→ 数据模型(含isSelected)+updateAppearancefigma-ios-listview-recognition→ 是否列表figma-ios-uicollectionview-codegen→ CV 骨架(识别为列表时必做)figma-ios-selection-interaction(本 Skill) → Delegate 交互figma-ios-rxswift-interaction-pattern→ 非列表按钮的点击绑定
常见错误与避坑指南
❌ 错误 1:忘记取消旧选中(单选模式)
问题:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// ❌ 错误:直接选中新项,旧项仍然是选中态
items[indexPath.item].isSelected = true
collectionView.reloadData()
}
结果: 多个 Cell 同时选中(违反单选逻辑)
修复:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// ✅ 正确:先取消所有,再选中当前
for i in 0..<items.count {
items[i].isSelected = false
}
items[indexPath.item].isSelected = true
collectionView.reloadData()
}
❌ 错误 2:忘记刷新 UI
问题:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
items[indexPath.item].isSelected.toggle()
// ❌ 错误:没有刷新 UI,数据变了但界面没变
}
结果: 选中态变化了,但 UI 没有更新
修复:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
items[indexPath.item].isSelected.toggle()
// ✅ 正确:刷新 UI
collectionView.reloadItems(at: [indexPath])
}
❌ 错误 3:单选模式刷新单个 Cell
问题:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
for i in 0..<items.count {
items[i].isSelected = false
}
items[indexPath.item].isSelected = true
// ❌ 错误:只刷新当前 Cell,旧选中的 Cell 仍显示选中态
collectionView.reloadItems(at: [indexPath])
}
结果: 新旧两个 Cell 都显示选中态
修复:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
for i in 0..<items.count {
items[i].isSelected = false
}
items[indexPath.item].isSelected = true
// ✅ 正确:刷新所有 Cell(或记录旧索引,刷新新旧两个)
collectionView.reloadData()
}
性能优化版本:
private var previousSelectedIndex: Int = 0
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// 取消旧选中
items[previousSelectedIndex].isSelected = false
// 选中新项
items[indexPath.item].isSelected = true
// 只刷新新旧两个 Cell
collectionView.reloadItems(at: [
IndexPath(item: previousSelectedIndex, section: 0),
indexPath
])
// 更新记录
previousSelectedIndex = indexPath.item
}
❌ 错误 4:didSet 与手动调用 updateAppearance 冲突
问题:
private var isSelected: Bool = false {
didSet {
updateAppearance() // didSet 会自动调用
}
}
func configure(isSelected: Bool) {
self.isSelected = isSelected
updateAppearance() // ❌ 重复调用
}
结果: updateAppearance() 被调用两次
修复:
// 方案 A:只在 didSet 中调用
private var isSelected: Bool = false {
didSet {
updateAppearance()
}
}
func configure(isSelected: Bool) {
self.isSelected = isSelected // ✅ 自动触发 didSet
}
或者:
// 方案 B:不用 didSet,手动调用
private var isSelected: Bool = false
func configure(isSelected: Bool) {
self.isSelected = isSelected
updateAppearance() // ✅ 手动调用
}
❌ 错误 5:多选模式下不允许全部取消
问题:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
items[indexPath.item].isSelected.toggle()
// ❌ 业务需求:至少选中一个,但没有验证
collectionView.reloadItems(at: [indexPath])
}
结果: 用户可以取消所有选中,违反业务规则
修复:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let currentItem = items[indexPath.item]
// 如果当前是选中态,且是唯一选中项,不允许取消
if currentItem.isSelected {
let selectedCount = items.filter { $0.isSelected }.count
if selectedCount == 1 {
// TODO(阶段3): 结合 PRD 决定交互(Toast 提示 / 禁用按钮 / 忽略)
print("至少需要选中一个标签")
return
}
}
// Toggle 选中态
items[indexPath.item].isSelected.toggle()
collectionView.reloadItems(at: [indexPath])
}
自动化检查清单
生成代码后,必须验证:
✅ 数据模型包含 isSelected 字段
✅ 默认选中项正确初始化(isSelected = true)
✅ 单选模式:点击时先取消所有,再选中当前
✅ 多选模式:点击时 Toggle 当前项
✅ UI 刷新逻辑正确(reloadData / reloadItems)
✅ RxSwift 使用 [weak self](避免循环引用)
✅ 留 TODO 注释提示业务逻辑
✅ didSet 与手动调用不冲突
✅ 多选模式考虑业务约束(如至少选中一个)
代码生成规范
1. 注释规范
// ========== 单选模式:取消所有选中,只选中当前项 ==========
// 或
// ========== 多选模式:Toggle 当前项 ==========
// 或
// ========== Toggle 模式:切换选中态 ==========
2. TODO 注释规范
// TODO(阶段3): 结合 PRD + 接口文档补业务逻辑(网络请求 / 页面跳转 / 数据联动等)
// 示例:
// - 网络请求:根据选中品类加载数据
// - 页面跳转:跳转到详情页
// - 数据联动:影响其他 UI 组件
3. 调试输出规范
print("选中品类: \(categories[indexPath.item].title)")
// 或
let selectedTags = tagItems.filter { $0.isSelected }.map { $0.title }
print("已选中标签: \(selectedTags)")
相关 Skill
- 总入口:[figma-ios-playbook](../figma-ios-playbook/SKILL.md)
- 状态识别:[figma-ios-component-state-recognition](../figma-ios-component-state-recognition/SKILL.md)
- ListView 识别:[figma-ios-listview-recognition](../figma-ios-listview-recognition/SKILL.md)
- 交互事件:[figma-ios-rxswift-interaction-pattern](../figma-ios-rxswift-interaction-pattern/SKILL.md)
- 标准组件:[figma-ios-standard-components](../figma-ios-standard-components/SKILL.md)
生成时间: 2026-03-31 核心价值: 自动生成选中态交互逻辑,减少重复代码,统一交互模式 适用范围: 所有涉及选择交互的 UI 组件(ListView、按钮组、Toggle 按钮等)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: mythkiven
- Source: mythkiven/figma-ios-codegen
- License: MIT
- Homepage: https://github.com/mythkiven/figma-ios-codegen/tree/main/docs
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.