Swift中variables值变化时执行方法
当variables值改变时,我需要执行一个函数。
我有一个singleton类包含一个名为labelChange
的共享variables。 这个variables的值来自另一个叫做Model
类。 我有两个VC类,其中一个有一个button和一个标签,第二个只有一个button。
当按下第一个VC类中的button时,我正在用这个func更新标签:
func updateLabel(){ self.label.text = SharingManager.sharedInstance.labelChange }
但是我想在labelChange
的值改变时调用相同的方法。 所以在button点击我只会更新labelChange
值,当这个事情发生时,我想用labelChange
的新值更新标签。 另外在第二个VC中,我能够更新labelChange
值,但是当这个值被改变时,我无法更新标签。
也许属性是解决scheme,但任何人都可以告诉我如何做到这一点。
第二次编辑:
单身职业:
class SharingManager { func updateLabel() { println(labelChange) ViewController().label.text = SharingManager.sharedInstance.labelChange } var labelChange: String = Model().callElements() { willSet { updateLabel() } } static let sharedInstance = SharingManager() }
首先VC:
class ViewController: UIViewController { @IBOutlet weak var label: UILabel! @IBAction func Button(sender: UIButton) { SViewController().updateMessageAndDismiss() } }
第二个VC:
func updateMessageAndDismiss() { SharingManager.sharedInstance.labelChange = modelFromS.callElements() self.dismissViewControllerAnimated(true, completion: nil) } @IBAction func b2(sender: UIButton) { updateMessageAndDismiss() }
我做了一些改进,但是我需要从单例中的第一个VC类引用一个标签。 所以我会更新单身人士VC的标签。
当我打印labelChange
的价值正在更新,一切都很好。 但是,当我尝试更新单身人士的标签上的值我收到一个错误:
意外地发现零,而解包一个可选的值
并且错误指向单例类的第四行。
你可以简单地使用一个属性observer作为variableslabelChange
,然后调用你想要在didSet
调用的函数(或者如果你想在调用它之前调用willSet
):
class SharingManager { var labelChange: String = Model().callElements() { didSet { updateLable() } } static let sharedInstance = SharingManager() }
这在Property Observers中有解释。
我不确定为什么当你尝试时这样做不起作用,但是如果你遇到麻烦,因为你试图调用的函数( updateLable
)在不同的类中,你可以在SharingManager
类中添加一个variables来存储调用didSet
时调用的函数,在这种情况下您将设置updateLable
。
编辑:
所以如果你想从ViewController中编辑一个标签,你需要在ViewController类中有updateLable()函数来更新标签,但是将这个函数存储在singleton类中,这样它就可以知道要调用哪个函数:
class SharingManager { static let sharedInstance = SharingManager() var updateLable: (() -> Void)? var labelChange: String = Model().callElements() { didSet { updateLable?() } } }
然后将其设置为你想调用函数的类,比如(假设updateLable是你要调用的函数):
SharingManager.sharedInstance.updateLable = updateLable
当然,你会想确保负责该函数的视图控制器仍然存在,所以单例类可以调用该函数。
如果您需要根据哪个视图控制器可见,调用不同的函数,则可能需要考虑键值观察 ,以便在某些variables的值发生更改时收到通知。
此外,你永远不想初始化一个视图控制器,然后立即设置视图控制器的IBOutlets,因为IBOutlets不会被初始化,直到它的视图实际上被加载。 您需要以某种方式使用现有的视图控制器对象。
希望这可以帮助。
还有另外一种方法,使用RxSwift:
-
将RxSwift和RxCocoa窗格添加到您的项目中
-
修改您的
SharingManager
:import RxSwift class SharingManager { static let sharedInstance = SharingManager() private let _labelUpdate = PublishSubject<String>() let onUpdateLabel: Observable<String>? // any object can subscribe to text change using this observable // call this method whenever you need to change text func triggerLabelUpdate(newValue: String) { _labelUpdate.onNext(newValue) } init() { onUpdateLabel = _labelUpdate.shareReplay(1) } }
-
在您的ViewController中,您可以通过两种方式订阅值更新:
一个。 订阅更新,并手动更改标签文本
// add this ivar somewhere in ViewController let disposeBag: DisposeBag() // put this somewhere in viewDidLoad SharingManager.sharedInstance.onUpdateLabel? .observeOn(MainScheduler.instance) // make sure we're on main thread .subscribeNext { [weak self] newValue in // do whatever you need with this string here, like: // self?.myLabel.text = newValue } .addDisposableTo(disposeBag) // for resource management
湾 将更新直接绑定到UILabel
// add this ivar somewhere in ViewController let disposeBag: DisposeBag() // put this somewhere in viewDidLoad SharingManager.sharedInstance.onUpdateLabel? .distinctUntilChanged() // only if value has been changed since previous value .observeOn(MainScheduler.instance) // do in main thread .bindTo(myLabel.rx_text) // will setText: for that label when value changed .addDisposableTo(disposeBag) // for resource management
别忘了在ViewController中import RxCocoa
。
触发事件只是打电话
SharingManager.sharedInstance.triggerLabelUpdate("whatever string here")
这里你可以find示例项目。 只要做pod update
并运行工作区文件。
var item = "initial value" { didSet { //called when item changes print("changed") } willSet { print("about to change") } } item = "p"
苹果提供这些属性声明types: –
1.计算属性: –
除了存储的属性,类,结构和枚举可以定义计算的属性,而实际上并不存储值。 相反,它们提供了一个getter和一个可选的setter来间接检索和设置其他属性和值。
var otherBool:Bool = false public var enable:Bool { get{ print("i can do editional work when setter set value ") return self.enable } set(newValue){ print("i can do editional work when setter set value ") self.otherBool = newValue } }
2.只读计算属性: –
具有getter但没有setter的计算属性被称为只读计算属性。 只读计算属性总是返回一个值,可以通过点语法访问,但不能设置为不同的值。
var volume: Double { return volume }
3.物业观察员: –
您可以select在属性中定义这些观察者中的一个或两个:
将在存储值之前调用willSet 。
在新值被存储之后立即调用didSet 。
public var totalSteps: Int = 0 { willSet(newTotalSteps) { print("About to set totalSteps to \(newTotalSteps)") } didSet { if totalSteps > oldValue { print("Added \(totalSteps - oldValue) steps") } } }
注意: – 更多信息继续专业链接 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html