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

iOS开发:如何用统一Action处理多个UISwitch的数组更新?

优化实现方案

首先明确核心问题:UISwitch的title属性并非用于存储开关对应的工具名(iOS原生开关本身不自带标题展示,标题通常是旁边独立的UILabel),所以你通过sender.title获取值必然返回nil,强制解包会导致崩溃。以下是几种统一处理所有开关的优化方式:

方法一:利用Tag与映射字典绑定工具名

通过给每个开关设置唯一Tag,再用字典建立Tag和工具名的对应关系,统一Action中通过Tag获取工具名:

import UIKit

class mainVC: UIViewController {
    
    var myEquippement: [String] = []
    // 定义Tag与工具名的映射表
    private let tagToToolMap: [Int: String] = [
        1: "Shovel",
        2: "Hammer",
        3: "Screwdriver",
        4: "Saw"
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func toggleToolSwitch(_ sender: UISwitch) {
        // 通过Tag获取对应工具名,避免强制解包
        guard let toolName = tagToToolMap[sender.tag] else { return }
        
        if sender.isOn {
            // 避免重复添加同一工具
            if !myEquippement.contains(toolName) {
                myEquippement.append(toolName)
            }
        } else {
            // 安全移除元素,避免数组中无该元素时崩溃
            if let index = myEquippement.firstIndex(of: toolName) {
                myEquippement.remove(at: index)
            }
        }
    }
}

操作步骤:

  • 在Storyboard中选中每个开关,在右侧Attributes Inspector的Tag栏设置对应数值(比如Shovel开关设为1,Hammer设为2)
  • 将所有开关的Action关联到toggleToolSwitch方法

方法二:利用AccessibilityLabel存储工具名

直接给每个开关的accessibilityLabel属性赋值为对应工具名,统一Action中读取该属性:

import UIKit

class mainVC: UIViewController {
    
    var myEquippement: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // 也可直接在Storyboard的Identity Inspector中设置每个开关的Accessibility Label
        shovelSwitch.accessibilityLabel = "Shovel"
        hammerSwitch.accessibilityLabel = "Hammer"
        screwdriverSwitch.accessibilityLabel = "Screwdriver"
        sawSwitch.accessibilityLabel = "Saw"
    }

    @IBAction func toggleToolSwitch(_ sender: UISwitch) {
        guard let toolName = sender.accessibilityLabel else { return }
        
        if sender.isOn {
            if !myEquippement.contains(toolName) {
                myEquippement.append(toolName)
            }
        } else {
            if let index = myEquippement.firstIndex(of: toolName) {
                myEquippement.remove(at: index)
            }
        }
    }
}

优势:无需维护映射字典,直接给开关绑定信息,操作简单。

方法三:自定义UISwitch子类绑定工具名

创建自定义Switch类,新增toolName属性直接存储对应工具名,这种方式更符合面向对象设计,适合工具列表较多的场景:

// 自定义Switch子类
import UIKit

class ToolSwitch: UISwitch {
    // 新增工具名属性
    var toolName: String?
}

// ViewController中使用
class mainVC: UIViewController {
    
    var myEquippement: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // 代码创建开关时直接设置toolName
        // let shovelSwitch = ToolSwitch()
        // shovelSwitch.toolName = "Shovel"
        
        // Storyboard中使用需:
        // 1. 将开关的Class改为ToolSwitch(Identity Inspector中设置)
        // 2. 在User Defined Runtime Attributes中添加key为toolName,类型String,值为对应工具名
    }

    @IBAction func toggleToolSwitch(_ sender: ToolSwitch) {
        guard let toolName = sender.toolName else { return }
        
        if sender.isOn {
            if !myEquippement.contains(toolName) {
                myEquippement.append(toolName)
            }
        } else {
            if let index = myEquippement.firstIndex(of: toolName) {
                myEquippement.remove(at: index)
            }
        }
    }
}

优势:工具名与开关直接绑定,后期维护工具列表时只需修改自定义类或属性设置,代码耦合度更低。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:40:22