点击条件部分的文本字段时应用程序冻结



我有一个可以用程序修改的文本字段。它运行良好,直到有条件地显示表单部分,在这种情况下,当我使用文本字段时,应用程序会冻结。

这是我的代码(我删除了不必要的东西(:

struct test: View {
@Environment(.presentationMode) var presentationMode
@State private var displaySection = true
@State private var amount: Double?
@FocusState private var isFocused: Bool

var body: some View {
NavigationView{
Form {
if displaySection {     // <-- works well without that condition, otherwise app freezes
Section {
VStack {
HStack {
Text("Amount EUR")
Spacer()
TextField("Type amount", value: $amount, format: .number)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.focused($isFocused)
}
Text("Set MAX (999)")
.frame(maxWidth: .infinity, alignment: .leading)
.onTapGesture {
isFocused = false
amount = 999
}
}
}
}
}
}
}
}

我需要在表格中隐藏一些部分,所以我坚持了下来,没有成功地避开这个问题。模拟器和设备上都出现了问题。

这种行为正常吗?或者有可能的解决方法吗?谢谢你的帮助:(

因此,对于英特尔和iOS 15.2上的Xcode 13.2.1,如果我在"Amount EUR"中键入超过三位数的数字,然后尝试"Set the Max to 999"(即三位数(,我只能在模拟器和实际设备上锁定此示例代码。

在SwiftUI的早期版本中,TextField唯一可以使用的输入绑定是String。尽管当前版本接受绑定到数字,但它的方式很可能是映射,并且底层机制仍然是原始的基于字符串的TextField(不幸的是,在带有附加键盘的TextField中键入仍然会呈现非数字字符,而不管键盘类型如何,就像我上次实验时一样https://gist.github.com/shufflingB/23daafa5253c3355cdf18934599cd54c)

无论出于何种原因,当输入超过三位数字时,这个新的(ish(映射过程似乎会变得混乱,并且默认情况下TextField会自动添加一个数字分组字符。

两种解决方案似乎解决了这个问题:

  1. 使用DispatchQueue.main.asyncAfterSet the Max ...触发的对amount的更改推送到稍后的状态更新周期

  2. 提供一个选项,从TextField中删除麻烦的分组字符。

struct ContentView: View {
@Environment(.presentationMode) var presentationMode
@State private var displaySection = true
@State private var amount: Double?
@FocusState private var isFocused: Bool
var body: some View {
NavigationView {
Form {
if displaySection {
Section {
VStack {
HStack {
Text("Amount EUR")
Spacer()
TextField("Type amount", value: $amount, format: .number)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.focused($isFocused)
/* Alternative to Dispatch, remove number grouping
TextField("Type amount", value: $amount, format: .number.grouping(.never))
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.focused($isFocused)
*/
}
Text("Set MAX (999)")
.frame(maxWidth: .infinity, alignment: .leading)
.onTapGesture {
isFocused = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // <- Push change to subsequent update cycle
amount = 999
}
}
}
}
}
}
}
}
}

分而治之。

你在你的应用程序中出现了一个非常奇怪的行为,我从来没有想过会出现这样的错误。我测试了你的代码,它实际上冻结了应用程序。

现在,我测试了下面的解决方案:将Section移动到一个单独的视图。在我的Xcode中,它是有效的。

struct Example: View {
@Environment(.presentationMode) var presentationMode
@State private var displaySection = true

var body: some View {
NavigationView{
Form {
if displaySection {     // <-- works well ALSO WITH that condition
ConditionalSection()
}

Button {
withAnimation {
displaySection.toggle()
}
} label: {
Text("Display or not display?")
}
}
}
}
}
struct ConditionalSection: View {
@State private var amount: Double?
@FocusState private var isFocused: Bool

var body: some View {
Section {
VStack {
HStack {
Text("Amount EUR")
Spacer()
TextField("Type amount", value: $amount, format: .number)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing)
.focused($isFocused)
}
Text("Set MAX (999)")
.frame(maxWidth: .infinity, alignment: .leading)
.onTapGesture {
isFocused = false
amount = 999
}
}
}
}
}

最新更新