Swiftui 如何通过另一个可观察的0对象观察已发布的属性-Swift Combine
[编辑] 我应该指出,我正在从大量传感器收集数据,并且不得不污染视图模型,也就是说,正在协调这一过程,大量的@Published和订户代码变得非常乏味和容易出错 我还编辑了代码,以便更能代表实际问题 [原件] 我试图减少使用发布服务器时观察另一个类的结果所需的代码量。我更愿意从生成结果的类发布结果,而不是将其传播回调用类 下面是一个简单的游乐场示例,说明了这个问题Swiftui 如何通过另一个可观察的0对象观察已发布的属性-Swift Combine,swiftui,combine,Swiftui,Combine,[编辑] 我应该指出,我正在从大量传感器收集数据,并且不得不污染视图模型,也就是说,正在协调这一过程,大量的@Published和订户代码变得非常乏味和容易出错 我还编辑了代码,以便更能代表实际问题 [原件] 我试图减少使用发布服务器时观察另一个类的结果所需的代码量。我更愿意从生成结果的类发布结果,而不是将其传播回调用类 下面是一个简单的游乐场示例,说明了这个问题 import SwiftUI import Combine class AnObservableObject: Observabl
import SwiftUI
import Combine
class AnObservableObject: ObservableObject {
@Published var flag: Bool = false
private var timerPub: Publishers.Autoconnect<Timer.TimerPublisher>
private var timerSub: AnyCancellable?
init() {
timerPub = Timer.publish(every: 1, on: .current, in: .common)
.autoconnect()
}
func start() {
timerSub = timerPub.sink { [self] _ in
toggleFlag()
}
}
func stop() {
timerSub?.cancel()
}
func toggleFlag() {
flag.toggle()
}
}
class AnotherObservableObject: ObservableObject {
let ao = AnObservableObject()
func start() {
ao.start()
}
func stop() {
ao.stop()
}
}
struct MyView: View {
@StateObject var ao = AnotherObservableObject()
var body: some View {
VStack {
if ao.ao.flag {
Image(systemName: "flag").foregroundColor(.green)
}
HStack {
Button(action: {ao.start()}, label: {
Text("Toggle Flag")
})
Button(action: {ao.stop()}, label: {
Text("Stop")
})
}
}
.padding()
}
}
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
// Make a UIHostingController
let viewController = UIHostingController(rootView: MyView())
// Assign it to the playground's liveView
PlaygroundPage.current.liveView = viewController
let myView = MyView()
导入快捷界面
进口联合收割机
类AnObservableObject:ObservableObject{
@已发布变量标志:Bool=false
private var timerPub:publisher.Autoconnect
private var timerSub:是否可以取消?
init(){
timerPub=Timer.publish(每:1,在:。当前,在:。公共)
.自动连接()
}
func start(){
timerSub=timerPub.sink{[self]\uuin
toggleFlag()
}
}
函数停止(){
timerSub?.cancel()
}
func toggleFlag(){
flag.toggle()
}
}
另一个ObserveObject类:ObserveObject{
设ao=AnObservableObject()
func start(){
ao.start()
}
函数停止(){
ao.停止()
}
}
结构MyView:View{
@StateObject var ao=另一个ObservableObject()
var body:一些观点{
VStack{
如果ao.ao.flag{
图像(系统名称:“标志”).foregroundColor(.绿色)
}
HStack{
按钮(操作:{ao.start()},标签:{
文本(“切换标志”)
})
按钮(操作:{ao.stop()},标签:{
文本(“停止”)
})
}
}
.padding()
}
}
导入PlaygroundSupport
PlaygroundPage.current.NeedsDefiniteExecution=true
//制作一个UIHostingController
让viewController=UIHostingController(rootView:MyView())
//将其指定给游乐场的liveView
PlaygroundPage.current.liveView=viewController
让myView=myView()
我实现这一目标的唯一方法是:
import SwiftUI
import Combine
class AnObservableObject: ObservableObject {
let flag = CurrentValueSubject<Bool, Never>(false)
private var subscriptions = Set<AnyCancellable>()
private var timerPub: Publishers.Autoconnect<Timer.TimerPublisher>
private var timerSub: AnyCancellable?
init() {
timerPub = Timer.publish(every: 1, on: .current, in: .common)
.autoconnect()
}
func start() {
timerSub = timerPub.sink { [self] _ in
toggleFlag()
}
}
func stop() {
timerSub?.cancel()
}
func flagPublisher() -> AnyPublisher<Bool, Never> {
return flag.eraseToAnyPublisher()
}
func toggleFlag() {
flag.value.toggle()
}
}
class AnotherObservableObject: ObservableObject {
let ao = AnObservableObject()
@Published var flag = false
init() {
let flagPublisher = ao.flagPublisher()
flagPublisher
.receive(on: DispatchQueue.main)
.assign(to: &$flag)
}
func start() {
ao.start()
}
func stop() {
ao.stop()
}
}
struct MyView: View {
@StateObject var ao = AnotherObservableObject()
var body: some View {
VStack {
if ao.flag {
Image(systemName: "flag").foregroundColor(.green)
}
HStack {
Button(action: {ao.start()}, label: {
Text("Toggle Flag")
})
Button(action: {ao.stop()}, label: {
Text("Stop")
})
}
}
.padding()
}
}
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
// Make a UIHostingController
let viewController = UIHostingController(rootView: MyView())
// Assign it to the playground's liveView
PlaygroundPage.current.liveView = viewController
let myView = MyView()
导入快捷界面
进口联合收割机
类AnObservableObject:ObservableObject{
let flag=CurrentValueSubject(false)
私有变量订阅=Set()
private var timerPub:publisher.Autoconnect
private var timerSub:是否可以取消?
init(){
timerPub=Timer.publish(每:1,在:。当前,在:。公共)
.自动连接()
}
func start(){
timerSub=timerPub.sink{[self]\uuin
toggleFlag()
}
}
函数停止(){
timerSub?.cancel()
}
func flagPublisher()->AnyPublisher{
return flag.eraseToAnyPublisher()
}
func toggleFlag(){
flag.value.toggle()
}
}
另一个ObserveObject类:ObserveObject{
设ao=AnObservableObject()
@发布的var标志=false
init(){
让flagPublisher=ao.flagPublisher()
旗舰出版商
.receive(在:DispatchQueue.main上)
.分配(给:&$flag)
}
func start(){
ao.start()
}
函数停止(){
ao.停止()
}
}
结构MyView:View{
@StateObject var ao=另一个ObservableObject()
var body:一些观点{
VStack{
如果是ao旗{
图像(系统名称:“标志”).foregroundColor(.绿色)
}
HStack{
按钮(操作:{ao.start()},标签:{
文本(“切换标志”)
})
按钮(操作:{ao.stop()},标签:{
文本(“停止”)
})
}
}
.padding()
}
}
导入PlaygroundSupport
PlaygroundPage.current.NeedsDefiniteExecution=true
//制作一个UIHostingController
让viewController=UIHostingController(rootView:MyView())
//将其指定给游乐场的liveView
PlaygroundPage.current.liveView=viewController
让myView=myView()
想法?你不需要一个
可观察对象来实现这一点;您可以直接在视图中观察计时器
struct MyView: View {
@State private var flag: Bool = false
@State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack {
if flag {
Image(systemName: "flag").foregroundColor(.green)
}
HStack {
Button(action: {start()}, label: {
Text("Toggle Flag")
})
Button(action: {stop()}, label: {
Text("Stop")
})
}
.onReceive(timer) { _ in
flag.toggle()
}
}
.padding()
}
func start() {
timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
}
func stop() {
timer.upstream.connect().cancel()
}
}
当您需要在视图中直接使用它时,通常需要一个可观察对象。你为什么需要一个?如果你没有,你可以只使用一个struct而不是AnObservableObject
,希望在几周内。你现在这样做是唯一的连锁方式them@loremipsum谢谢,希望如此!如果SwitftUI、Combine和pro Mac获得重大更新,则应为退出活动!谢谢你的回答,我现在已经更新了我的代码,并希望提供更好的解释。考虑收集位置数据,操作它,然后将一些结果传递给视图,我想这样做,而不必将这些返回到VIEW模型。这只是我收集的数据点之一。