如何在SwiftUI的主体方法中初始化派生变量(或替代方法)

时间:2019-10-23 00:40:16

标签: binding initialization swiftui

我正在尝试在swiftUI视图的body方法中找出正确的方法来初始化派生变量。一个示例是可编辑整数的字符串值,然后将在TextField中对其进行编辑。例如,整数可以是@ObservedObject的一部分。我无法弄清楚这样做的任何远程清洁方法。

我已经研究过使用自定义初始化程序,但这似乎不是正确的选择。我什至不确定这段代码是否会在适当的时间运行。

我也尝试过将.onAppear方法用于TextField,但是在重建视图时,似乎没有重新执行此方法。

简化示例:

final class Values : ObservableObject {
  @Published var count: Int = 0;
}

var sharedValues = Values()

struct ContentView : View {
  @ObservedObject var values = sharedValues
  var body: some View {
    VStack {
      Button(
        action: { self.add() },
        label: { Text("Plus")}
      )
      InnerView()
    }
  }
  func add() { values.count += 1 }
}

struct InnerView : View {
  @ObservedObject var values = sharedValues
  @State private var text = ""
  var body: some View {
    // text = String(value.count) - what I want to do
    TextField("", text: $text, onEditingChanged: updateCount)
      .textFieldStyle(RoundedBorderTextFieldStyle())
  }
  func updateCount(updated: Bool) {  /* this isn't important in this context */}
}

我希望能够从外部更新sharedValues并在MyView中看到更新。在此示例中,我想按下按钮以使用更新后的文本值更新文本字段。但是我想不出一种方法,可以在代码执行的适当位置计算计数值的字符串表示形式。

我已经尝试了多种方法来获得这种结果,但结果却很简短。

2 个答案:

答案 0 :(得分:0)

我不确定我是否正确理解了您的问题,但是如果您只是想使用按钮来更改数字,请将该数字显示在文本字段中,然后进行编辑在那里,您不需要ObserverableObject或多个视图。 这是如何执行此操作的示例:

struct ContentView: View {
    @State var count = 0
    @State var countStr = ""
    var body: some View {
        VStack {
            Button(action: {
                self.count += 1
                self.countStr = "\(self.count)"
            }) {
                Text("Plus")
            }
            TextField("", text: $countStr, onEditingChanged: updateCount)
        }
    }
    func updateCount(updated: Bool) { /* this isn't important in this context */ }
}

答案 1 :(得分:0)

使用TextField的value init method。这取值为2 Way Binding。因此,它会自动从文本字段和按钮中更新计数。

import SwiftUI
import Combine

final class Values : ObservableObject {
  @Published var count: Int = 0;
}

var sharedValues = Values()

struct AndrewVoelkel : View {
  @ObservedObject var values = sharedValues
  var body: some View {
    HStack {
        InnerView()
        VStack{
          Button(
            action: { self.add() },
            label: { Text("+")}
          )
          Button(
            action: { self.sub() },
            label: { Text("-")}
          )
        }.font(.headline)
    }.padding()
  }
  func add() { values.count += 1 }
  func sub() { values.count -= 1 }
}

struct InnerView : View {
  @ObservedObject var values = sharedValues
  var body: some View {
    TextField("", value: $values.count, formatter: NumberFormatter())
      .textFieldStyle(RoundedBorderTextFieldStyle())
  }
}