从自己的 PickerView 获取值
Getting Values from own PickerView
我是 Swift 的新手,目前我正在开发自己的计时器应用程序以供练习。 (我没有分镜)
现在我遇到了一个问题,我创建了一个名为“TimePickerView”的视图(下面的代码),我在其中创建了自己的选择器。然后我在我的应用程序的另一部分与其他视图(在视图中)一起使用该 TimePickerView。在那个视图中,我想选择我的时间,但我不知道如何获得选择器的值(顺便说一下,选择器工作)
这是我的 TimePickerView
import SwiftUI
struct TimePickerView: View {
@State private var selectedTimeIndexSecond = 0
@State private var selectedTimeIndexMinutes = 0
@State private var seconds : [Int] = Array(0...59)
@State private var minutes : [Int] = Array(0...59)
var body: some View {
VStack{
Text("Select Your Time")
HStack{
//minutes-Picker
Picker("select time", selection: $selectedTimeIndexMinutes, content: {
ForEach(0..<minutes.count, content: {
index in
Text("\(minutes[index]) min").tag(index)
})
})
.padding()
.frame(width: 120)
.clipped()
//seconds-Picker
Picker("select time", selection: $selectedTimeIndexSecond, content: {
ForEach(0..<seconds.count, content: {
index in
Text("\(seconds[index]) sec").tag(index)
})
})
.padding()
.frame(width: 120)
.clipped()
Spacer()
}
Text("You picked the time")
.multilineTextAlignment(.center)
.font(.title2)
.padding()
Text("\(minutes[selectedTimeIndexMinutes]) min : \(seconds[selectedTimeIndexSecond]) sec")
.font(.title)
.bold()
.padding(.top, -14.0)
}
}
func getValues() -> (Int, Int) {
return (self.minutes[selectedTimeIndexMinutes] ,self.seconds[selectedTimeIndexSecond])
}
}
这就是我想使用我的选择器的视图,但我不知道如何从选择器中获取这些值:
struct SetTimerView: View {
@State var timepicker = TimePickerView()
var body: some View {
NavigationView{
VStack{
//Select the time
timepicker
//Timer variables (This doesn't work)
var timerTime = timepicker.getValues()
var minutes = timerTime.0
var seconds = timerTime.1
Spacer()
let valid : Bool = isValid(timerTime: minutes+seconds)
//Confirm the time
NavigationLink(
destination:
getRightView(
validBool: valid,
timerTime: minutes*60 + seconds),
label: {
ConfirmButtonView(buttonText: "Confirm")
});
Spacer()
}
}
}
func isValid(timerTime : Int) -> Bool {
if (timerTime == 0) {
return false
} else {
return true
}
}
@ViewBuilder func getRightView(validBool : Bool, timerTime : Int) -> some View{
if (validBool == true) {
TimerView(userTime: CGFloat(timerTime), name: "David", isActive: true)
} else {
UnvalidTimeView()
}
}
}
我认为主要问题是误解了数据和视图之间的概念。
首先你需要一个模型 将覆盖你的数据(在单独的 swift 文件中创建它):
import Foundation
class Time: ObservableObject {
@Published var selectedTimeIndexMinutes: Int = 0
@Published var selectedTimeIndexSecond: Int = 0
}
关注 ObservableObject
以便 swiftUI 可以轻松检测到触发任何活动视图重绘的更改。
接下来我尝试更改视图中模型的值
import SwiftUI
struct TimePickerView: View {
@EnvironmentObject var timeData: Time
@State private var seconds : [Int] = Array(0...59)
@State private var minutes : [Int] = Array(0...59)
var body: some View {
VStack{
Text("Select Your Time")
HStack{
//minutes-Picker
Picker("select time", selection: $timeData.selectedTimeIndexMinutes, content: {
ForEach(0..<minutes.count, content: {
index in
Text("\(minutes[index]) min").tag(index)
})
})
.padding()
.frame(width: 120)
.clipped()
//seconds-Picker
Picker("select time", selection: $timeData.selectedTimeIndexSecond, content: {
ForEach(0..<seconds.count, content: {
index in
Text("\(seconds[index]) sec").tag(index)
})
})
.padding()
.frame(width: 120)
.clipped()
Spacer()
}
Text("You picked the time")
.multilineTextAlignment(.center)
.font(.title2)
.padding()
Text("\(timeData.selectedTimeIndexMinutes) min : \(timeData.selectedTimeIndexSecond) sec")
.font(.title)
.bold()
.padding(.top, -14.0)
}
}
}
struct TimePickerView_Previews: PreviewProvider {
static var previews: some View {
TimePickerView()
.environmentObject(Time())
}
}
如您所见,我没有使用 @Blinding
,而是将我们的模型与视图连接起来
在下一个视图中我可以看到更改,我创建了一个新视图,因为您的示例具有此处未指明的视图...
import SwiftUI
struct ReuseDataFromPicker: View {
@EnvironmentObject var timeData: Time
var body: some View {
VStack{
Text("You selected")
Text("\(timeData.selectedTimeIndexMinutes) min and \(timeData.selectedTimeIndexSecond) sec")
}
}
}
struct ReuseDataFromPicker_Previews: PreviewProvider {
static var previews: some View {
ReuseDataFromPicker()
.environmentObject(Time())
}
}
并在内容视图中收集所有内容
struct ContentView: View {
var body: some View {
TabView {
TimePickerView()
.tabItem {Label("Set Timer", systemImage: "clock.arrow.2.circlepath")}
ReuseDataFromPicker()
.tabItem {Label("Show Timer", systemImage: "hourglass")}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(Time())
}
}
这样您就可以轻松地在任何其他视图上更改或重复使用您的数据
我是 Swift 的新手,目前我正在开发自己的计时器应用程序以供练习。 (我没有分镜)
现在我遇到了一个问题,我创建了一个名为“TimePickerView”的视图(下面的代码),我在其中创建了自己的选择器。然后我在我的应用程序的另一部分与其他视图(在视图中)一起使用该 TimePickerView。在那个视图中,我想选择我的时间,但我不知道如何获得选择器的值(顺便说一下,选择器工作)
这是我的 TimePickerView
import SwiftUI
struct TimePickerView: View {
@State private var selectedTimeIndexSecond = 0
@State private var selectedTimeIndexMinutes = 0
@State private var seconds : [Int] = Array(0...59)
@State private var minutes : [Int] = Array(0...59)
var body: some View {
VStack{
Text("Select Your Time")
HStack{
//minutes-Picker
Picker("select time", selection: $selectedTimeIndexMinutes, content: {
ForEach(0..<minutes.count, content: {
index in
Text("\(minutes[index]) min").tag(index)
})
})
.padding()
.frame(width: 120)
.clipped()
//seconds-Picker
Picker("select time", selection: $selectedTimeIndexSecond, content: {
ForEach(0..<seconds.count, content: {
index in
Text("\(seconds[index]) sec").tag(index)
})
})
.padding()
.frame(width: 120)
.clipped()
Spacer()
}
Text("You picked the time")
.multilineTextAlignment(.center)
.font(.title2)
.padding()
Text("\(minutes[selectedTimeIndexMinutes]) min : \(seconds[selectedTimeIndexSecond]) sec")
.font(.title)
.bold()
.padding(.top, -14.0)
}
}
func getValues() -> (Int, Int) {
return (self.minutes[selectedTimeIndexMinutes] ,self.seconds[selectedTimeIndexSecond])
}
}
这就是我想使用我的选择器的视图,但我不知道如何从选择器中获取这些值:
struct SetTimerView: View {
@State var timepicker = TimePickerView()
var body: some View {
NavigationView{
VStack{
//Select the time
timepicker
//Timer variables (This doesn't work)
var timerTime = timepicker.getValues()
var minutes = timerTime.0
var seconds = timerTime.1
Spacer()
let valid : Bool = isValid(timerTime: minutes+seconds)
//Confirm the time
NavigationLink(
destination:
getRightView(
validBool: valid,
timerTime: minutes*60 + seconds),
label: {
ConfirmButtonView(buttonText: "Confirm")
});
Spacer()
}
}
}
func isValid(timerTime : Int) -> Bool {
if (timerTime == 0) {
return false
} else {
return true
}
}
@ViewBuilder func getRightView(validBool : Bool, timerTime : Int) -> some View{
if (validBool == true) {
TimerView(userTime: CGFloat(timerTime), name: "David", isActive: true)
} else {
UnvalidTimeView()
}
}
}
我认为主要问题是误解了数据和视图之间的概念。
首先你需要一个模型 将覆盖你的数据(在单独的 swift 文件中创建它):
import Foundation
class Time: ObservableObject {
@Published var selectedTimeIndexMinutes: Int = 0
@Published var selectedTimeIndexSecond: Int = 0
}
关注 ObservableObject
以便 swiftUI 可以轻松检测到触发任何活动视图重绘的更改。
接下来我尝试更改视图中模型的值
import SwiftUI
struct TimePickerView: View {
@EnvironmentObject var timeData: Time
@State private var seconds : [Int] = Array(0...59)
@State private var minutes : [Int] = Array(0...59)
var body: some View {
VStack{
Text("Select Your Time")
HStack{
//minutes-Picker
Picker("select time", selection: $timeData.selectedTimeIndexMinutes, content: {
ForEach(0..<minutes.count, content: {
index in
Text("\(minutes[index]) min").tag(index)
})
})
.padding()
.frame(width: 120)
.clipped()
//seconds-Picker
Picker("select time", selection: $timeData.selectedTimeIndexSecond, content: {
ForEach(0..<seconds.count, content: {
index in
Text("\(seconds[index]) sec").tag(index)
})
})
.padding()
.frame(width: 120)
.clipped()
Spacer()
}
Text("You picked the time")
.multilineTextAlignment(.center)
.font(.title2)
.padding()
Text("\(timeData.selectedTimeIndexMinutes) min : \(timeData.selectedTimeIndexSecond) sec")
.font(.title)
.bold()
.padding(.top, -14.0)
}
}
}
struct TimePickerView_Previews: PreviewProvider {
static var previews: some View {
TimePickerView()
.environmentObject(Time())
}
}
如您所见,我没有使用 @Blinding
,而是将我们的模型与视图连接起来
在下一个视图中我可以看到更改,我创建了一个新视图,因为您的示例具有此处未指明的视图...
import SwiftUI
struct ReuseDataFromPicker: View {
@EnvironmentObject var timeData: Time
var body: some View {
VStack{
Text("You selected")
Text("\(timeData.selectedTimeIndexMinutes) min and \(timeData.selectedTimeIndexSecond) sec")
}
}
}
struct ReuseDataFromPicker_Previews: PreviewProvider {
static var previews: some View {
ReuseDataFromPicker()
.environmentObject(Time())
}
}
并在内容视图中收集所有内容
struct ContentView: View {
var body: some View {
TabView {
TimePickerView()
.tabItem {Label("Set Timer", systemImage: "clock.arrow.2.circlepath")}
ReuseDataFromPicker()
.tabItem {Label("Show Timer", systemImage: "hourglass")}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(Time())
}
}
这样您就可以轻松地在任何其他视图上更改或重复使用您的数据