简体   繁体   English

带有 animation 的 TextField 使应用程序崩溃并失去焦点

[英]TextField with animation crashes app and looses focus

Minimal reproducible example:最小可重现示例:

In SceneDelegate.swift :SceneDelegate.swift

let contentView = Container()

In ContentView.swift :ContentView.swift

struct SwiftUIView: View {
    @State var text: String = ""

    var body: some View {
        VStack {
            CustomTextFieldView(text: $text)
        }
    }
}

struct Container: View {

    @State var bool: Bool = false
    @State var text: String = ""

    var body: some View {

        Button(action: {
            self.bool.toggle()
        }) {
            Text("Sheet!")
        }
        .sheet(isPresented: $bool) {
            SwiftUIView()
        }
    }
}

In CustomTextField.swift :CustomTextField.swift中:

struct CustomTextFieldView: View {

    @Binding var text: String
    @State var editing: Bool = false


    var body: some View {
        Group {
            if self.editing {
                textField
                    .background(Color.red)
            } else {
                ZStack(alignment: .leading) {
                    textField
                        .background(Color.green)
                    Text("Placeholder")
                }
            }
        }
        .onTapGesture {
            withAnimation {
                self.editing = true
            }
        }
    }

    var textField: some View {
        TextField("", text: $text)
    }

Problem:问题:

After running the above code and focusing the text field, the app crashes.运行上述代码并聚焦文本字段后,应用程序崩溃了。 Some things I noticed:我注意到的一些事情:

  1. If I remove the withAnimation code, or the ZStack in CustomTextField file, the app doesn't crash, but the TextField looses focus.如果我删除withAnimation代码或CustomTextField文件中的ZStack ,应用程序不会崩溃,但 TextField 会失去焦点。
  2. If I remove the VStack in SwiftUIView , the app doesn't crash, but the TextField looses focus.如果我删除VStack中的SwiftUIView ,应用程序不会崩溃,但 TextField 会失去焦点。
  3. If I use a NavigationLink or present the TextField without a sheet, the app doesn't crash, but the TextField looses focus.如果我使用 NavigationLink 或在没有工作表的情况下显示 TextField,应用程序不会崩溃,但 TextField 会失去焦点。

Questions:问题:

  • Is this a problem in the current version of SwiftUI?这是SwiftUI当前版本的问题吗?
  • Is there a solution to this problem using SwiftUI?是否有使用 SwiftUI 解决此问题的方法? I want to stay out of ViewRepresentables as much as possible.我想尽可能远离 ViewRepresentables。
  • How can I keep the focus of the TextField after the body is recalculated because of a change in state?由于 state 的变化,在重新计算正文后,如何保持 TextField 的焦点?
  1. How can I keep the focus of the TextField after the body is recalculated because of a change in state?由于 state 的变化,在重新计算正文后,如何保持 TextField 的焦点?

You have two of them.你有两个。 Two different TextField could not be in editing state at the same time.两个不同的TextField不能同时在编辑state。

The approach suggested by Asperi is the only possible. Asperi 建议的方法是唯一可行的方法。

The reason, why your code crash is not easy explain, but expected in current SwiftUI.你的代码崩溃的原因不容易解释,但在当前 SwiftUI 中是预期的。

You have to understand, that Group is not a standard container, it just like a "block" on which you can apply some modifiers.您必须了解,Group 不是标准容器,它就像一个“块”,您可以在其上应用一些修饰符。 Removing Group and using wraping body in ViewBuilder删除组并在 ViewBuilder 中使用包装体

struct CustomTextFieldView: View {

    @Binding var text: String
    @State var editing: Bool = false

    @ViewBuilder
    var body: some View {
            if self.editing {
                TextField("", text: $text)
                    .background(Color.red)
                    .onTapGesture {
                        self.editing.toggle()
                }
            } else {
                ZStack(alignment: .leading) {
                    TextField("", text: $text)
                        .background(Color.green)
                        .onTapGesture {
                                self.editing.toggle()
                        }
                }
        }

    }
}

the code will stop to crash, but there is other issue, the keyboard will dismiss immediately.代码将停止崩溃,但还有其他问题,键盘将立即关闭。 That is due the tap gesture applied.这是由于应用了点击手势。

So, believe or not, you have to use ONE TextField ONLY.所以,不管你信不信,你必须只使用一个 TextField。

struct CustomTextFieldView: View {

    @Binding var text: String
    @State var editing = false

    var textField: some View {
        TextField("", text: $text, onEditingChanged: { edit in
            self.editing = edit
        })
    }

    var body: some View {

        textField.background(editing ? Color.green : Color.red)

    }
}

Use this custom text field elsewhere in your code, as you want根据需要在代码的其他位置使用此自定义文本字段

Try the following for CustomTextFieldView (tested & works with Xcode 11.2 / iOS 13.2)CustomTextFieldView尝试以下操作(已测试并适用于 Xcode 11.2 / iOS 13.2)

struct CustomTextFieldView: View {

    @Binding var text: String
    @State var editing: Bool = false


    var body: some View {
        TextField("", text: $text)
            .background(self.editing ? Color.red : Color.green)
            .onTapGesture {
                withAnimation {
                    self.editing = true
                }
            }
    }
}

How can I keep the focus of the TextField after the body is recalculated because of a change in state?由于 state 的变化,在重新计算正文后,如何保持 TextField 的焦点?

You don't loose focus, you just remove entire text field, so the solution is not replace text field, but modify its property, ie background.你没有失去焦点,你只是删除了整个文本字段,所以解决方案不是替换文本字段,而是修改它的属性,即背景。 It's ok to put it into ZStack, but keep it one.放到ZStack里没问题,但还是留着吧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 swiftUI 文本字段和 WKWebView 文本字段时应用程序崩溃 - App crashes when using a swiftUI textfield and a WKWebView textfield SCLAlertView - 专注于文本字段 - SCLAlertView - Focus on textfield 更改焦点的文本字段 - Change textfield on focus 使用 textFieldShouldReturn 方法将焦点移动到下一个 textField 它在 Apple TV App 中不起作用 - Using textFieldShouldReturn method to move the focus to next textField it is not working in Apple TV App 当我的文本字段为空时,我的应用程序崩溃了,我如何响应一个空的文本字段? - When my textfield is empty, my app crashes how do I respond to an empty text field? Pickerview 在文本字段中第二次单击时显示为空,当我按下完成或取消应用程序崩溃时 - Pickerview is showing empty on second click in the textfield, adn when i press Done or Cancel the App crashes 文本框自动对焦无法正常工作 - textfield auto focus not working properly Lottie 动画在“needsUpdate”上崩溃? - Lottie animation crashes on "needsUpdate"? 带有动画的 UIPageViewController 使应用程序崩溃 - UIPageViewController with animation crashes application 文本字段框架动画与键盘动画持续时间不同步 - Textfield frame animation is not in sync with keyboard animation duration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM