swift - 从自己的 PickerView 获取值
问题描述
我是 Swift 新手,我目前正在开发自己的计时器应用程序以用于练习目的。(我在没有情节提要的情况下这样做)
现在我有一个问题,我创建了一个名为“TimePickerView”(下面的代码)的视图,在那里我创建了自己的 Picker。然后我在我的应用程序的另一部分中使用该 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])
}
}
这就是我想使用我的 Picker 的视图,但我不知道如何从 Picker 中获取这些值:
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())
}
}
像这样,您可以轻松地在任何其他视图上更改或重用您的数据
推荐阅读
- python - 如何在python中使用带有断言概念的if语句
- arrays - 映射时 React 中的过滤器方法不起作用
- javascript - 将模态背景更改为动画背景
- awk - 使用 SED 或 AWK 跨多行查找和替换字符串
- asp.net - 在单独的 Docker 容器中使用数据库时添加迁移会引发错误
- sql - 在 PostgreSQL 中使用 AGE 函数订购时间戳持续时间
- regex - 如何匹配正则表达式中的不同组
- javascript - 如何使用javascript将json数据格式从数组更改为对象数组?
- javascript - 如何使用选定的下拉列表使用受尊重的时区进行日期时间选择器?
- c# - 查找两个数组之间的匹配序列(模式匹配)C#