[英]iOS Combine Framework - Publisher Only Publishes Once and Then Never Again
I am trying to use the iOS 13 Combine framework in conjunction with some UIKit controls.我正在尝试将 iOS 13 Combine 框架与一些 UIKit 控件结合使用。 I want to set up a viewcontroller that contains a switch that enables/disables a button whenever the switch is toggled on/off.
我想设置一个包含一个开关的视图控制器,该开关在开关打开/关闭时启用/禁用按钮。 According to Apple's documentation, UIKit controls have built-in support for Combine publishers, etc. so this should be possible.
根据 Apple 的文档,UIKit 控件内置了对 Combine 发布者等的支持,所以这应该是可能的。
I have a viewcontroller that contains a UISwitch and a UIButton, as shown here:我有一个包含 UISwitch 和 UIButton 的视图控制器,如下所示:
link to screenshot of my viewcontroller链接到我的视图控制器的屏幕截图
and here is my code:这是我的代码:
import Combine
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var mySwitch: UISwitch!
@IBOutlet weak var myButton: UIButton!
var myCancellable: AnyCancellable?
override func viewDidLoad() {
super.viewDidLoad()
mySwitch.isOn = true // Set initial state of switch
myButton.setTitle("Enabled", for: .normal)
myButton.setTitle("Disabled", for: .disabled)
myCancellable = mySwitch.publisher(for: \.isOn)
.subscribe(on: RunLoop.main)
.assign(to: \.isEnabled, on: myButton)
}
}
The above code should (or so I thought) emit the value of the switch's .isOn
property, whenever that property changes, and assign the value to the button's .isEnabled
property.上面的代码应该(或者我认为)发出开关的
.isOn
属性的值,每当该属性更改时,并将该值分配给按钮的.isEnabled
属性。 If it is running the way I would expect, that means that when the switch is toggled ON the button title should read "Enabled" and the button should be enabled.如果它以我期望的方式运行,这意味着当开关切换为 ON 时,按钮标题应显示为“已启用”,并且应启用该按钮。 When the UISwitch is toggled OFF, then the button title should read "Disabled" and the button should be disabled.
当 UISwitch 切换为 OFF 时,按钮标题应显示为“已禁用”并且按钮应被禁用。
But it does not behave the way I am expecting.但它的行为并不像我期望的那样。 The value from the switch's publisher is only emitted once, when the publisher is first set up inside
viewDidLoad()
.当第一次在
viewDidLoad()
设置发布者时,来自 switch 发布者的值只发出一次。 When tapping on the switch to toggle it on or off, it never emits a value ever again.当点击开关打开或关闭它时,它永远不会再发出一个值。 I can tell it is at least emitting the value once, because if I change the initial state of the switch to either on or off, the button is set to the expected state when the viewcontroller is loaded.
我可以告诉它至少发出一次值,因为如果我将开关的初始状态更改为打开或关闭,则在加载视图控制器时按钮将设置为预期状态。
Typically you are supposed to keep a strong reference to the publisher, or else the publisher/subscriber will be terminated immediately, so that's why I am holding a reference with the myCancellable
variable.通常,您应该保留对发布者的强引用,否则发布者/订阅者将立即终止,这就是为什么我使用
myCancellable
变量持有引用的myCancellable
。 But this does not fix the issue, the values are still not emitted when tapping on the switch.但这并不能解决问题,点击开关时仍然没有发出值。
Does anyone have any ideas on how to fix this?有没有人对如何解决这个问题有任何想法? This seems like it should be a simple "Hello World" type of example using Combine, and I don't know what I am missing here.
这似乎应该是一个简单的“Hello World”类型的使用 Combine 的例子,我不知道我在这里遗漏了什么。
A common mistake is thinking that UISwitch
's isOn
property is KVO-compliant.一个常见的错误是认为
UISwitch
的isOn
属性是 KVO 兼容的。 Sadly, it isn't.可悲的是,事实并非如此。 You cannot use
publisher(for:)
to observe it.您不能使用
publisher(for:)
来观察它。
Create an @IBAction
in your ViewController
, and connect the switch's Value Changed event to it.在您的
ViewController
创建一个@IBAction
,并将开关的 Value Changed 事件连接到它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.