点击条件部分中的文本字段时应用程序冻结
App freeze when tap on textfield in conditional section
我有一个可以通过编程方式修改的文本字段。
它工作正常,直到有条件地显示表单部分,在这种情况下,当我使用文本字段时应用程序会冻结。
这是我的代码(我删除了不必要的东西):
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
}
}
}
}
}
}
}
}
我需要在表单中隐藏一些部分,所以我一直坚持下去,没有成功回避这个问题。问题出现在模拟器和设备上。
这种行为是否正常,或者是否有可能的解决方法?
感谢您的帮助:)
分而治之。
你在你的应用程序中出现了一个非常奇怪的行为,我永远无法想象这样的错误。我测试了你的代码,它实际上冻结了应用程序。
现在,我测试了以下解决方案:将您的 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
}
}
}
}
}
所以在 Intel 上使用 Xcode 13.2.1 和 iOS 15.2 如果我输入一个数字,我只能在模拟器和真实设备上将此示例代码设为 lock-up 'Amount EUR' 中超过三位数,然后尝试 'Set the Max to 999' 即三位数。
在以前的 SwiftUI 版本中,TextField 唯一可以使用的输入绑定是 String。似乎尽管当前版本接受绑定到数字,但它这样做的方式是映射,并且底层机制仍然是基于原始字符串的 TextField 的机制(不幸的是,在带有附加键盘的 TextField 中键入仍然呈现 non-numeric 字符,不管键盘类型如何,就像我上次试验时那样 https://gist.github.com/shufflingB/23daafa5253c3355cdf18934599cd54c)
无论出于何种原因,当输入的数字超过三位时,这个新的(大概)映射过程似乎会变得混乱,然后 TextField 默认会自动添加数字分组字符。
两个 work-arounds 似乎解决了问题:
使用 DispatchQueue.main.asyncAfter
将由 Set the Max ...
触发的 amount
的更改推送到稍后的状态更新周期
提供一个选项以从 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
}
}
}
}
}
}
}
}
}
我有一个可以通过编程方式修改的文本字段。 它工作正常,直到有条件地显示表单部分,在这种情况下,当我使用文本字段时应用程序会冻结。
这是我的代码(我删除了不必要的东西):
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
}
}
}
}
}
}
}
}
我需要在表单中隐藏一些部分,所以我一直坚持下去,没有成功回避这个问题。问题出现在模拟器和设备上。
这种行为是否正常,或者是否有可能的解决方法? 感谢您的帮助:)
分而治之。
你在你的应用程序中出现了一个非常奇怪的行为,我永远无法想象这样的错误。我测试了你的代码,它实际上冻结了应用程序。
现在,我测试了以下解决方案:将您的 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
}
}
}
}
}
所以在 Intel 上使用 Xcode 13.2.1 和 iOS 15.2 如果我输入一个数字,我只能在模拟器和真实设备上将此示例代码设为 lock-up 'Amount EUR' 中超过三位数,然后尝试 'Set the Max to 999' 即三位数。
在以前的 SwiftUI 版本中,TextField 唯一可以使用的输入绑定是 String。似乎尽管当前版本接受绑定到数字,但它这样做的方式是映射,并且底层机制仍然是基于原始字符串的 TextField 的机制(不幸的是,在带有附加键盘的 TextField 中键入仍然呈现 non-numeric 字符,不管键盘类型如何,就像我上次试验时那样 https://gist.github.com/shufflingB/23daafa5253c3355cdf18934599cd54c)
无论出于何种原因,当输入的数字超过三位时,这个新的(大概)映射过程似乎会变得混乱,然后 TextField 默认会自动添加数字分组字符。
两个 work-arounds 似乎解决了问题:
使用
将由DispatchQueue.main.asyncAfter
Set the Max ...
触发的amount
的更改推送到稍后的状态更新周期提供一个选项以从 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
}
}
}
}
}
}
}
}
}