首页 > 解决方案 > 从自己的 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()
        }
    }
    
}

标签: swiftviewswiftuitimerpicker

解决方案


我认为主要问题是对数据和视图之间的概念的误解。

首先,您需要一个模型女巫来覆盖您的数据(在单独的 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())

    }
}

像这样,您可以轻松地在任何其他视图上更改或重用您的数据


推荐阅读