首页 > 解决方案 > 一些显示/隐藏循环后,形式中的选轮器消失

问题描述

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

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

在此处输入图像描述

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()
        }
    }
}

标签: swiftuipicker

解决方案


使用.idfor Pickers 似乎有所帮助。使用 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()
    }
}

推荐阅读