Swiftui 在另一个视图中使用一个视图的计算值
Swiftui Using a calculated value from 1 view in another view
我对 Swiftui 比较陌生,目前正在开发我的第二个应用程序,它比第一个应用程序复杂得多。
我在几天来一直试图解决的一个特定要求上遇到了瓶颈,现在我在使用大量关于 State/Binding/ObservableObject 等
的视频和文章后绕圈子
我正在开发一个高尔夫计分应用程序,用户将依次通过每个洞并输入他们的分数,将进行各种计算并显示在视图中。其中之一是总得分。当他们移动到第二个洞时,将遵循相同的过程,但有一个额外的计算需要将洞 1 和洞 2 的总分加在一起。我尝试过的各种方法都以 0 或我想记住更多的错误消息,当然太多了,无法包含在此处!!
如果有任何帮助,我将不胜感激,我已将我的代码包含在下面(为此目的 post 进行了删减),其中包括一些注释来解释我需要做什么,我希望这些注释是清楚的。如果任何人都可以将我的代码改编成可以正常工作的东西,那么我可以看看它们是如何组合在一起的。
提前致谢
开始查看
// 这个画面只是用来开始一个回合的。它将带您到 1 号洞,从那里,1 号洞的导航链接将带您到 2 号洞,依此类推。
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: Hole1View()) {
Text("Start Round")
.frame(width: 300, height: 30)
.font(.system(size: 18, weight: .bold, design: .rounded))
.lineLimit(1)
.multilineTextAlignment(.center)
.padding(18)
.background(Color.yellow)
.foregroundColor(Color.blue)
.cornerRadius(10)
.border(Color.blue, width: 10)
.cornerRadius(1)
}
}
}
}
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
洞 1 视图
// 在此视图中,您将输入各种信息,并且视图中将包含各种计算。其中一个计算是计算一个值(Hole1totalpoints),这将在下一个视图的计算中需要。
import SwiftUI
struct Hole1View: View {
@State private var hole1gross = 0
var hole1totalpoints: Int {
let hole1points = hole1gross * 3
return hole1points
}
var body: some View {
// On this view you will enter various information and there will be various calculations to include in the View. One of the calculations is to calculate a value (Hole1totalpoints) which will be required in calculations in the next view.
Stepper("\(hole1gross)", value: $hole1gross, in: 0...15)
.frame(width: 300, height: 35, alignment: .leading)
.font(.system(size: 16, weight: .bold, design: .rounded))
.minimumScaleFactor(0.6)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text("Calculated Value \(hole1totalpoints)")
NavigationLink(destination: Hole2View()) {
Text("Go to hole 2")
}
}
}
struct Hole1View_Previews: PreviewProvider {
static var previews: some View {
Hole1View()
}
}
洞 2 视图
// 在此视图中,您将输入各种信息,并且视图中将包含各种计算。其中一项计算是计算一个值(Hole2totalpoints)。其中一个计算需要包含前一个视图 (Hole1View) 的值 hole1totalpoints,以计算可在 View 中使用的 2 个视图 (hole1totalpoints+hole2totalpoints) 的总点数。
import SwiftUI
struct Hole2View: View {
@State private var hole2gross = 0
@State private var hole2totpoints = 0
var hole2totalpoints: Int {
let hole1points = hole2gross * 2
return hole1points
}
var body: some View {
Stepper("\(hole2gross)", value: $hole2gross, in: 0...15)
.frame(width: 300, height: 35, alignment: .leading)
.font(.system(size: 16, weight: .bold, design: .rounded))
.minimumScaleFactor(0.6)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text("Calculated Value \(hole2totalpoints)")
}
}
struct Hole2View_Previews: PreviewProvider {
static var previews: some View {
Hole2View()
}
}
您可以使用@ObservableObject 或@EnvironmentObject 来完成此操作。我选择通过 props 传递 @ObservableObject 来显示它,但你可以轻松地将其更改为仅在顶部注入我的 ScoreManager
对象,同时使用 environmentObject
:
struct ContentView: View {
@ObservedObject var scoreManager = ScoreManager()
var body: some View {
NavigationView {
NavigationLink(destination: Hole1View(scoreManager: scoreManager)) {
Text("Start Round")
.frame(width: 300, height: 30)
.font(.system(size: 18, weight: .bold, design: .rounded))
.lineLimit(1)
.multilineTextAlignment(.center)
.padding(18)
.background(Color.yellow)
.foregroundColor(Color.blue)
.cornerRadius(10)
.border(Color.blue, width: 10)
.cornerRadius(1)
}
}
}
}
class ScoreManager : ObservableObject {
@Published var hole1gross = 0
var hole1totalpoints: Int {
let hole1points = hole1gross * 3
return hole1points
}
@Published var hole2gross = 0
@Published var hole2totpoints = 0
var hole2totalpoints: Int {
//do any calculations here relating to hole 1 points, since you have access to both
let hole1points = hole2gross * 2
return hole1points
}
var hole1AndHole2Points : Int {
hole1totalpoints + hole2totalpoints
}
}
struct Hole1View: View {
@ObservedObject var scoreManager : ScoreManager
var body: some View {
Stepper("\(scoreManager.hole1gross)", value: $scoreManager.hole1gross, in: 0...15)
.frame(width: 300, height: 35, alignment: .leading)
.font(.system(size: 16, weight: .bold, design: .rounded))
.minimumScaleFactor(0.6)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text("Calculated Value \(scoreManager.hole1totalpoints)")
NavigationLink(destination: Hole2View(scoreManager: scoreManager)) {
Text("Go to hole 2")
}
}
}
struct Hole2View: View {
@ObservedObject var scoreManager : ScoreManager
var body: some View {
Stepper("\(scoreManager.hole2gross)", value: $scoreManager.hole2gross, in: 0...15)
.frame(width: 300, height: 35, alignment: .leading)
.font(.system(size: 16, weight: .bold, design: .rounded))
.minimumScaleFactor(0.6)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text("Calculated Value \(scoreManager.hole2totalpoints)")
Text("Both holes: \(scoreManager.hole1AndHole2Points)")
}
}
ContentView
现在创建一个 ScoreManager
。它通过 NavigationLinks
中的其他视图向下传递。其他视图以该对象的相同版本结束(它不会在新视图中重新创建——它们都具有对原始对象的相同引用)。然后,在原始版本中,您可以访问所有想要的乐谱。我创建了 hole1AndHole2Points
,我认为它可以满足您的描述。您可以在第 2 洞的最后 Text
项中看到反映的值。
如果你想走环境对象路线,代码会非常相似。有关该系统的更多阅读:https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views
我对 Swiftui 比较陌生,目前正在开发我的第二个应用程序,它比第一个应用程序复杂得多。 我在几天来一直试图解决的一个特定要求上遇到了瓶颈,现在我在使用大量关于 State/Binding/ObservableObject 等
的视频和文章后绕圈子我正在开发一个高尔夫计分应用程序,用户将依次通过每个洞并输入他们的分数,将进行各种计算并显示在视图中。其中之一是总得分。当他们移动到第二个洞时,将遵循相同的过程,但有一个额外的计算需要将洞 1 和洞 2 的总分加在一起。我尝试过的各种方法都以 0 或我想记住更多的错误消息,当然太多了,无法包含在此处!!
如果有任何帮助,我将不胜感激,我已将我的代码包含在下面(为此目的 post 进行了删减),其中包括一些注释来解释我需要做什么,我希望这些注释是清楚的。如果任何人都可以将我的代码改编成可以正常工作的东西,那么我可以看看它们是如何组合在一起的。
提前致谢
开始查看
// 这个画面只是用来开始一个回合的。它将带您到 1 号洞,从那里,1 号洞的导航链接将带您到 2 号洞,依此类推。
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: Hole1View()) {
Text("Start Round")
.frame(width: 300, height: 30)
.font(.system(size: 18, weight: .bold, design: .rounded))
.lineLimit(1)
.multilineTextAlignment(.center)
.padding(18)
.background(Color.yellow)
.foregroundColor(Color.blue)
.cornerRadius(10)
.border(Color.blue, width: 10)
.cornerRadius(1)
}
}
}
}
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
洞 1 视图
// 在此视图中,您将输入各种信息,并且视图中将包含各种计算。其中一个计算是计算一个值(Hole1totalpoints),这将在下一个视图的计算中需要。
import SwiftUI
struct Hole1View: View {
@State private var hole1gross = 0
var hole1totalpoints: Int {
let hole1points = hole1gross * 3
return hole1points
}
var body: some View {
// On this view you will enter various information and there will be various calculations to include in the View. One of the calculations is to calculate a value (Hole1totalpoints) which will be required in calculations in the next view.
Stepper("\(hole1gross)", value: $hole1gross, in: 0...15)
.frame(width: 300, height: 35, alignment: .leading)
.font(.system(size: 16, weight: .bold, design: .rounded))
.minimumScaleFactor(0.6)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text("Calculated Value \(hole1totalpoints)")
NavigationLink(destination: Hole2View()) {
Text("Go to hole 2")
}
}
}
struct Hole1View_Previews: PreviewProvider {
static var previews: some View {
Hole1View()
}
}
洞 2 视图
// 在此视图中,您将输入各种信息,并且视图中将包含各种计算。其中一项计算是计算一个值(Hole2totalpoints)。其中一个计算需要包含前一个视图 (Hole1View) 的值 hole1totalpoints,以计算可在 View 中使用的 2 个视图 (hole1totalpoints+hole2totalpoints) 的总点数。
import SwiftUI
struct Hole2View: View {
@State private var hole2gross = 0
@State private var hole2totpoints = 0
var hole2totalpoints: Int {
let hole1points = hole2gross * 2
return hole1points
}
var body: some View {
Stepper("\(hole2gross)", value: $hole2gross, in: 0...15)
.frame(width: 300, height: 35, alignment: .leading)
.font(.system(size: 16, weight: .bold, design: .rounded))
.minimumScaleFactor(0.6)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text("Calculated Value \(hole2totalpoints)")
}
}
struct Hole2View_Previews: PreviewProvider {
static var previews: some View {
Hole2View()
}
}
您可以使用@ObservableObject 或@EnvironmentObject 来完成此操作。我选择通过 props 传递 @ObservableObject 来显示它,但你可以轻松地将其更改为仅在顶部注入我的 ScoreManager
对象,同时使用 environmentObject
:
struct ContentView: View {
@ObservedObject var scoreManager = ScoreManager()
var body: some View {
NavigationView {
NavigationLink(destination: Hole1View(scoreManager: scoreManager)) {
Text("Start Round")
.frame(width: 300, height: 30)
.font(.system(size: 18, weight: .bold, design: .rounded))
.lineLimit(1)
.multilineTextAlignment(.center)
.padding(18)
.background(Color.yellow)
.foregroundColor(Color.blue)
.cornerRadius(10)
.border(Color.blue, width: 10)
.cornerRadius(1)
}
}
}
}
class ScoreManager : ObservableObject {
@Published var hole1gross = 0
var hole1totalpoints: Int {
let hole1points = hole1gross * 3
return hole1points
}
@Published var hole2gross = 0
@Published var hole2totpoints = 0
var hole2totalpoints: Int {
//do any calculations here relating to hole 1 points, since you have access to both
let hole1points = hole2gross * 2
return hole1points
}
var hole1AndHole2Points : Int {
hole1totalpoints + hole2totalpoints
}
}
struct Hole1View: View {
@ObservedObject var scoreManager : ScoreManager
var body: some View {
Stepper("\(scoreManager.hole1gross)", value: $scoreManager.hole1gross, in: 0...15)
.frame(width: 300, height: 35, alignment: .leading)
.font(.system(size: 16, weight: .bold, design: .rounded))
.minimumScaleFactor(0.6)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text("Calculated Value \(scoreManager.hole1totalpoints)")
NavigationLink(destination: Hole2View(scoreManager: scoreManager)) {
Text("Go to hole 2")
}
}
}
struct Hole2View: View {
@ObservedObject var scoreManager : ScoreManager
var body: some View {
Stepper("\(scoreManager.hole2gross)", value: $scoreManager.hole2gross, in: 0...15)
.frame(width: 300, height: 35, alignment: .leading)
.font(.system(size: 16, weight: .bold, design: .rounded))
.minimumScaleFactor(0.6)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text("Calculated Value \(scoreManager.hole2totalpoints)")
Text("Both holes: \(scoreManager.hole1AndHole2Points)")
}
}
ContentView
现在创建一个 ScoreManager
。它通过 NavigationLinks
中的其他视图向下传递。其他视图以该对象的相同版本结束(它不会在新视图中重新创建——它们都具有对原始对象的相同引用)。然后,在原始版本中,您可以访问所有想要的乐谱。我创建了 hole1AndHole2Points
,我认为它可以满足您的描述。您可以在第 2 洞的最后 Text
项中看到反映的值。
如果你想走环境对象路线,代码会非常相似。有关该系统的更多阅读:https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views