Swift技术问题:如何从其他函数访问函数内部的常量
问题描述
我尝试从minusBtn函数中访问plusBtn函数内定义的常量buttonSabah,并在@objc func buttonAddSabah函数中使用它。我知道可以将常量定义在ViewController类外部,但想了解如何直接访问该函数内的常量,需要在指定位置通过判断该常量内容控制按钮激活状态。
现有代码
import UIKit class ViewController: UIViewController { func plusBtn() { let buttonSabah = UIButton() buttonSabah.frame = CGRect(x: 100, y: 500, width: 20, height: 20) buttonSabah.backgroundColor = .red buttonSabah.setTitle("+", for: .normal) buttonSabah.addTarget(self, action: #selector(buttonAddSabah), for: .touchUpInside) view.addSubview(buttonSabah) } @objc func buttonAddSabah(sender: UIButton!) { sabah += 1 sabahLabel.text = String(sabah) if sabahLabel.text == "-" { // 此处需要访问上述常量编写控制逻辑 } } }
解决方案
首先明确:函数内用let定义的buttonSabah是局部常量,作用域仅限plusBtn函数内部,外部函数无法直接访问。以下是几种无需将常量放在类外的可行方案:
方案一:将buttonSabah升级为类实例属性
把buttonSabah定义在ViewController类内部、所有函数外部,作为实例属性,类内所有方法都能直接访问:
import UIKit class ViewController: UIViewController { // 定义为类的实例常量(按钮创建后无需重新赋值,用let即可) let buttonSabah = UIButton() func plusBtn() { buttonSabah.frame = CGRect(x: 100, y: 500, width: 20, height: 20) buttonSabah.backgroundColor = .red buttonSabah.setTitle("+", for: .normal) buttonSabah.addTarget(self, action: #selector(buttonAddSabah), for: .touchUpInside) view.addSubview(buttonSabah) } @objc func buttonAddSabah(sender: UIButton!) { sabah += 1 sabahLabel.text = String(sabah) if sabahLabel.text == "-" { // 直接访问buttonSabah控制激活状态 buttonSabah.isEnabled = false } } }
方案二:通过按钮tag识别定位
如果buttonAddSabah是多个按钮的响应方法,可以给buttonSabah设置唯一tag,在响应方法中通过tag查找目标按钮:
import UIKit class ViewController: UIViewController { func plusBtn() { let buttonSabah = UIButton() buttonSabah.frame = CGRect(x: 100, y: 500, width: 20, height: 20) buttonSabah.backgroundColor = .red buttonSabah.setTitle("+", for: .normal) buttonSabah.tag = 100 // 设置唯一标识tag buttonSabah.addTarget(self, action: #selector(buttonAddSabah), for: .touchUpInside) view.addSubview(buttonSabah) } @objc func buttonAddSabah(sender: UIButton!) { sabah += 1 sabahLabel.text = String(sabah) if sabahLabel.text == "-" { // 通过tag找到buttonSabah并控制状态 if let targetBtn = view.viewWithTag(100) as? UIButton { targetBtn.isEnabled = false } } } }
方案三:闭包捕获(不推荐)
虽然可以通过闭包让外部函数捕获局部常量,但这种方式会增加代码复杂度,对于UI按钮的场景完全没必要,因此不推荐使用。
如果minusBtn函数也需要访问该按钮,上述两种方案同样适用:方案一中直接调用buttonSabah即可,方案二中同样通过viewWithTag查找。
内容的提问来源于stack exchange,提问作者armut
相关产品推荐
相关产品推荐

