更改对象属性的函数调用不会更新视图。

huangapple go评论65阅读模式
英文:

Function call to change properties of an object does not update the view

问题

I understand your request for code translation. Here's the translated code without any additional content:

我创建了一个类,它有一个用于更新其值的函数。当点击按钮时,调用此函数,但我创建的视图不会更新。这是我拥有的内容的一个非常基本版本。由于这不是精确的代码,而是演示一般结构的简化版本,因此语法可能不正确。



```swift
class TaskCounter: Identifiable
{
    let id: UUID
    var count: Int
    var name: String

    init(id: UUID = UUID(), count: Int = 0, name: String)
    {
        self.id = id
        self.count = count
        self.name = name
    }
    
    func update() -> Int
    {
        count += 1
    }
}

extension TaskCounter
{
    sampleTasks = 
    [ TaskCounter("A"), 
      TaskCounter("B"),
      TaskCounter("C")
    ]
}

视图结构

ContentView
{
    @State tasks: [TaskCounter] = TaskCounter.sampleData
    ...
    /// 当用户在底部栏上选择某个选项时,在其上方加载较小的视图
    SmallerView(tasks: $tasks)
    ...
}
SmallerView
{
    @Binding var tasks: [TaskCounter]
    
    /// 任务列表
    ForEach { task in tasks
        SmallerCardView(task: $task)
    }
}
SmallerCardView
{
    @Binding task: TaskCounter

    /// 在按钮按下时,更新任务对象的内部值
    Button(action: { task.update() }, label: { Rectangle() })
}

我尝试使内部子视图使用状态,因为我读到更改状态将强制视图更新。我的对 @State 和 @Binding 的理解是否正确,@State 保存顶层数据,而 @Binding 用于可以操作该数据的较小子视图?


<details>
<summary>英文:</summary>

I have made a class, and it has a function that updates its value. When a button is clicked, this function is called, but the view I made does not update. Here is a very basic version of what I have. The syntax may be incorrect as this is not the exact code but a simplified version demonstrating the general structure.

The Class

class TaskCounter: Identifiable
{
let id:UUID
var count:Int
var name:String

init (id:UUID = UUID(), count:Int = 0, name:String)
{
    self.id = id
    self.count = count
    self.name = name
}
func update() -&gt; Int
{
    count+=1
}

}
extension TaskCounter
{
sampleTasks =
[ TaskCounter("A"),
TaskCounter("B"),
TaskCounter("C")
]
}


The View Structure

ContentView
{
@State tasks[TaskCounter] = TaskCounter.sampleData
...
/// When user selects some option on the bottom bar load smaller view above it
SmallerView(tasks: $tasks)
...
}


SmallerView
{
@Binding var:[TaskCounter] tasks

///List of tasks
ForEach { task in tasks
    SmallerCardView(task: $task)
}

}


SmallerCardView
{
@Binding task:TaskCounter

/// On button press, update the internal value of the task object
Button (action: { task.update()},label {Rectangle()})

}


I tried to make the internal subviews use state, since I read that changes to state would force the view to update. Is my understanding of @State and @Binding correct in that @State holds the top level data, and @Binding is for smaller subviews that can manipulate that data?

</details>


# 答案1
**得分**: 1

你应该通过使用ObservableObject协议,向你的**count**变量添加一个"listener"。

```swift
struct ContentView: View {
    @StateObject private var taskCounter = TaskCounter(name: "Counter")

    var body: some View {
        VStack {
            Text("Count: \(taskCounter.count)")
                .font(.title)
            
            CountButton(taskCounter: taskCounter)
        }
        .padding()
    }
}

struct CountButton: View {
    @ObservedObject var taskCounter: TaskCounter

    var body: some View {
        Button(action: {
            taskCounter.update()
        }) {
            Text("Increment Count")
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(8)
        }
    }
}

class TaskCounter: ObservableObject {
    let id = UUID()
    @Published var count: Int
    var name: String

    init(count: Int = 0, name: String) {
        self.count = count
        self.name = name
    }

    func update() {
        count += 1
    }
}

希望这有所帮助。

英文:

You should add a "listener" to your count variable by using the ObservableObject protocol

struct ContentView: View {
    @StateObject private var taskCounter = TaskCounter(name: &quot;Counter&quot;)

    var body: some View {
        VStack {
            Text(&quot;Count: \(taskCounter.count)&quot;)
                .font(.title)
            
            CountButton(taskCounter: taskCounter)
        }
        .padding()
    }
}

struct CountButton: View {
    @ObservedObject var taskCounter: TaskCounter

    var body: some View {
        Button(action: {
            taskCounter.update()
        }) {
            Text(&quot;Increment Count&quot;)
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(8)
        }
    }
}

class TaskCounter: ObservableObject {
    let id = UUID()
    @Published var count: Int
    var name: String

    init(count: Int = 0, name: String) {
        self.count = count
        self.name = name
    }

    func update() {
        count += 1
    }
}

huangapple
  • 本文由 发表于 2023年5月11日 10:48:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76223831.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定