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
相关产品推荐
相关产品推荐

