一些显示/隐藏循环后,形式中的选轮器消失
Posted
技术标签:
【中文标题】一些显示/隐藏循环后,形式中的选轮器消失【英文标题】:Wheel Pickers in form disappear after some show/hide cycles 【发布时间】:2019-12-07 08:50:20 【问题描述】:我在条件子视图中嵌入了车轮选择器时遇到了一种奇怪的行为。显示子视图时,有时不会显示值。在两个条件视图之间切换,这些值有时会重新出现。我附上了显示行为和完整代码的动画。我找不到原因。
更新:我已经尝试了很多方法来找出原因。即使将显示的子表单简化为一个单一的选择器,用硬编码的 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()
【问题讨论】:
确认 ios 13,.2 的行为,在 13.1 中没有发生 -> 我认为这是 Apple 错误 顺便说一句:你为什么不比较简单的方法? "if openSetting == .start " 并且使用 "withAnimation() self.openSetting.wrappedValue = (self.openSetting.wrappedValue == self.setting) ? OpenSetting.none : self.setting " @Chris:感谢您的确认。所以我需要找到一个解决方法。也感谢其他提示! 这个 SwiftUI 的 bug 真的让我很烦。我已经尽一切努力让它工作,但即使在一个简单的场景中,选轮器也不会出现。有人对此有解决方案吗? 【参考方案1】:将.id
用于Picker
s 似乎有所帮助。使用 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()
【讨论】:
更新:不幸的是,该解决方案确实解决了最初的问题,但它引入了一个新的严重问题:使用其中一个***更改值时,应用程序崩溃并显示“下标超出范围”系统库中的错误。【参考方案2】:你可以这样解决:
if openSetting == .start
TimePicker1(minutes: $startMinutes, seconds: $startSeconds)
.......
if openSetting == .end
TimePicker1(minutes: $endMinutes, seconds: $endSeconds).id(1)
一个带id
,另一个不带id
。
【讨论】:
以上是关于一些显示/隐藏循环后,形式中的选轮器消失的主要内容,如果未能解决你的问题,请参考以下文章