AgentStack
SKILL verified MIT Self-run

Figma Ios Selection Interaction

skill-mythkiven-figma-ios-codegen-figma-ios-selection-interaction · by mythkiven

>-

No reviews yet
0 installs
7 views
0.0% view→install

Install

$ agentstack add skill-mythkiven-figma-ios-codegen-figma-ios-selection-interaction

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Figma Ios Selection Interaction? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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 等)

生成顺序:

  1. figma-ios-component-state-recognition → 数据模型(含 isSelected)+ updateAppearance
  2. figma-ios-listview-recognition → 是否列表
  3. figma-ios-uicollectionview-codegen → CV 骨架(识别为列表时必做
  4. figma-ios-selection-interaction(本 Skill) → Delegate 交互
  5. 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.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.