我在单独的文件中有以下两个结构,并显示在contentView中。我试图理解的是如何将contentView保持为只显示和组织UI。将我的所有其他视图放在单独的文件中。我的第一个想法是,正确的方法是使用静态变量,这些变量由按下按钮时调用的函数更新。但按钮文本没有相应更新。因为它们是根据CCD_ 1动态更新的。
更新:
我试图通过使用协议和委托来解决这个问题,但没有成功。根据我的理解,此代理调用应该在另一端接收并更新structcop.ID
,并且更改应该反映在内容视图中。
FILE 1
import SwiftUI
struct structdispatch: View {
var radio:RadioDelegate?
func send() {
radio?.update()
self.debug()
}
var body: some View {
Button(action: self.send)
{Text("DISPATCHER")}
}
func debug() {
print("Button is sending?")
}
}
struct structdispatch_Previews: PreviewProvider {
static var previews: some View {
structdispatch()
}
}
**FILE 2:**
import SwiftUI
protocol RadioDelegate {
func update()
}
struct structcop: View, RadioDelegate {
@State public var ID:Int = 3
func update(){
print("message recieved")
self.ID += 1
print(self.ID)
}
var body: some View {
Text(String(self.ID))
}
}
struct structcop_Previews: PreviewProvider {
static var previews: some View {
structcop()
}
}
DEBUG CONSOLE RETURNS:
The Button is working
视图会根据一些内部DynamicProperty
更改进行更新,如@State
,因此这里有可能的解决方案
使用Xcode 12/iOS 14 进行测试
struct structcop: View {
static public var ID = 3
@State private var localID = Self.ID {
didSet {
Self.ID = localID
}
}
var body: some View {
Button(action: printme)
{Text(String(localID))}
}
func printme(){
self.localID = 5
print(structcop.ID)
}
}
解决方案:
经过一番挖掘,我有了一个可行的解决方案,但我仍然很好奇是否有一种方法可以在保持动态视图更新的同时修改其他结构的属性。
解决方案:将数据存储在可观察对象中以供显示,该对象将读取或充当用户正在交互的模型。
可观察对象是数据的自定义对象,可以从SwiftUI环境中的存储绑定到视图。SwiftUI监视可观察对象的任何可能影响视图的更改,并在更改后显示视图的正确版本 -苹果
声明了一个新的模型类型,它符合Combine框架中的ObservableObject协议。SwiftUI订阅可观察对象,并在数据更改时更新需要刷新的相关视图。SceneDelegate.swift需要在根视图中添加.environmentObject(_:)
修饰符。
ObservableObject中声明的属性应设置为@State
0,以便订阅者能够接受任何更改。
对于测试代码,我创建了一个名为总部的ObservableObject
import SwiftUI
import Combine
final class hq: ObservableObject {
@Published var info = headQuarters
}
let headQuarters = hqData(id: 3)
struct hqData {
var id: Int
mutating func bump() {
self.id += 1
}
}
在我的struct dispatch
中,我订阅了该对象,并调用了一个函数,每当按下按钮时,该函数就会迭代模型中的id。我的struct cop
也订阅了该对象,因此模型和按钮文本也相应地进行了更新。
struct dispatch: View {
@EnvironmentObject private var hq: headqarters
var body: some View {
Button(action: {self.hq.info.bump()}) {
Text("Button")
}
}
}
struct cop: View {
@EnvironmentObject private var hq: headquarters
var body: some View {
Text(String(self.hq.info.id))
}
}