在某些显示/隐藏循环后,表单中的轮式拾取器消失了

时间:2019-12-07 08:50:20

标签: swiftui picker

我在条件子视图中嵌入车轮选择器时遇到奇怪的行为。显示子视图时,有时不显示值。在两个条件视图之间切换时,有时会再次显示这些值。我已附上动画,显示了行为和完整代码。我找不到原因。

更新:我已经尝试了很多事情来找到原因。即使将显示子窗体简化为仅一个选择器,用硬编码的Text()条目替换了foreach循环,删除了选择器上的框架和剪辑,它仍然不起作用。

enter image description here

import SwiftUI

fileprivate enum OpenSetting {
    case none, start, end
}

struct ContentView: View {
    @State private var openSetting = OpenSetting.none
    @State private var startMinutes = 0
    @State private var startSeconds = 10
    @State private var endMinutes = 3
    @State private var endSeconds = 0

    var body: some View {
        NavigationView {
            Form {
                // Start
                TimeSetting(
                    title: "Start",
                    color: Color.yellow,
                    minutes: startMinutes,
                    seconds: startSeconds,
                    setting: .start,
                    openSetting: $openSetting
                )
                if openSetting == .start {
                    TimePicker(minutes: $startMinutes, seconds: $startSeconds)
                }

                // End
                TimeSetting(
                    title: "End",
                    color: Color.green,
                    minutes: endMinutes,
                    seconds: endSeconds,
                    setting: .end,
                    openSetting: $openSetting
                )
                if openSetting == .end {
                    TimePicker(minutes: $endMinutes, seconds: $endSeconds)
                }
            }
                .navigationBarTitle("Test")
                .navigationBarItems(
                    trailing: Text("Start")
            )

        }

    }
}

struct TimeSetting: View {
    var title: String
    var color: Color
    var minutes: Int
    var seconds: Int
    fileprivate var setting: OpenSetting
    fileprivate var openSetting: Binding<OpenSetting>

    var body: some View {
        HStack {
            Text(title)
            Spacer()
            ZStack {
                RoundedRectangle(cornerRadius: 4)
                    .fill(color)
                Text(toTime(minutes: minutes, seconds: seconds))
            }
            .frame(width: 64, height: 32)
        }
        .contentShape(Rectangle())
        .onTapGesture {
            withAnimation() {
                self.openSetting.wrappedValue = (self.openSetting.wrappedValue == self.setting) ? OpenSetting.none : self.setting
            }
        }
    }

    func toTime(minutes: Int, seconds: Int) -> String {
        let timeString = String(format: "%02d", minutes) + ":" + String(format: "%02d", seconds)
        return timeString
    }
}

struct TimePicker: View {
    var minutes: Binding<Int>
    var seconds: Binding<Int>

    var body: some View {
        HStack() {
            Spacer()
            Picker(selection: minutes, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
                }.pickerStyle(WheelPickerStyle()).frame(width: 50).clipped()
            Text("Min.")
            Picker(selection: seconds, label: EmptyView()) {
                ForEach((0...59), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
                }.pickerStyle(WheelPickerStyle()).frame(width: 50).clipped()
            Text("Sec.")
            Spacer()
        }
    }
}

2 个答案:

答案 0 :(得分:2)

.id中使用Picker似乎有所帮助。在Xcode 11.2 / iOS 13.2上进行了测试。

var body: some View {
    HStack() {
        Spacer()
        Picker(selection: minutes, label: EmptyView()) {
            ForEach((0...9), id: \.self) { ix in
                Text("\(ix)").tag(ix)
            }
            }.pickerStyle(WheelPickerStyle()).frame(width: 50).clipped()
        .id(UUID().uuidString)
        Text("Min.")
        Picker(selection: seconds, label: EmptyView()) {
            ForEach((0...59), id: \.self) { ix in
                Text("\(ix)").tag(ix)
            }
            }.pickerStyle(WheelPickerStyle()).frame(width: 50).clipped()
        .id(UUID().uuidString)
        Text("Sec.")
        Spacer()
    }
}

答案 1 :(得分:0)

您可以通过以下方式解决它:

         if openSetting == .start {
                TimePicker1(minutes: $startMinutes, seconds: $startSeconds)
            }
          .......
            if openSetting == .end {
                TimePicker1(minutes: $endMinutes, seconds: $endSeconds).id(1)
            }

一个带有id,另一个没有id