首页 > 解决方案 > 带有动画的 SwiftUI 表单布局错误

问题描述

我已经阅读了关于这个问题的类似描述,但没有一个是完全正确的,而且解决方法似乎不适用于我。我想知道是否有其他人经历过这种情况,是否有办法使用动画来显示表单,或者这是否值得将其作为错误报告给 Apple。

我有ContentView几个按钮可以切换布尔值。一个按钮简单地切换布尔值,而另一个按钮在动画块内切换布尔值。布尔值控制显示两个表单视图中的哪一个。在没有动画的情况下切换时,表单会正确呈现。但是当在动画块中切换时,表单呈现不正确。

这是“正常”(又名ReviewSheet)视图。

显示 ReviewSheet 的 ContentView

当您点击“编辑”时,它会切换到BugSheet视图。看起来不错。

不显示动画的 BugSheet

如果您选择“Bug It”按钮,这BugSheet就是呈现方式:

以动画形式显示的 BugSheet

现在,表单中BugSheet的第一部分header与放大的内容区域重叠,在第二部分中,Text不再呈现多行(使用lineLimit修饰符无效)。

以下是这三个视图中的每一个的代码:

struct ContentView: View {
    @State private var isEditing = false
    
    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            HStack {
                Text("Form Bug")
                    .font(.title)
                Spacer()
                
                // This "Edit" button just toggles isEditing and doing this
                // the switch between BugSheet and ReviewSheet appears as you
                // would expect.
                Button(isEditing ? "Save 1" : "Edit") {
                    isEditing.toggle()
                }
                
                // This "Edit" button also toggle isEditing but does so within
                // an animation block. The switch between BugSheet and ReviewSheet
                // leaves the Form rendered improperly.
                Button(isEditing ? "Save 2" :
                        "Bug It") {
                    withAnimation {
                        isEditing.toggle()
                    }
                }
            }
            .padding()
            .background(Color.orange)
            .foregroundColor(.white)
            
            if isEditing {
                BugSheet()
            } else {
                ReviewSheet()
            }
        }
    }
}

struct ReviewSheet: View {
    @State private var titleText: String = "Example Title"
    @State private var shortDescription: String = "This should work"
    @State private var keywords: String = "swiftui, apple, form, bug"
    
    let longDescription = "The rain in Spain stays mainly on the Plains even while the quick brown fox jumps over the lazy dog."
    
    var body: some View {
        Form {
            Section(header: Text("Title")) {
                Text(titleText)
            }
            Section(header: Text("Details")) {
                Text(shortDescription)
                Text(longDescription)
                Text(keywords)
            }
        }
    }
}

struct BugSheet: View {
    
    enum Field: Hashable {
        case title
        case shorty
        case keywords
    }
    
    @FocusState private var focusedField: Field?
    
    @State private var titleText: String = ""
    @State private var shortDescription: String = ""
    @State private var keywords: String = ""
    @State private var notes: String = "This is a starter note."
    
    let longDescription = "The rain in Spain stays mainly on the Plains even while the quick brown fox jumps over the lazy dog."
    
    private func gotoField(_ field: Field) {
        focusedField = field
    }
    
    var body: some View {
        Form {
            Section(header: Text("Title")) {
                TextField("title here", text: $titleText, onCommit: {gotoField(.shorty)})
                    .autocapitalization(.words)
                    .disableAutocorrection(false)
                    .keyboardType(.default)
                    .focused($focusedField, equals: .title)
            }
            
            Section(header: Text("Details")) {
                TextField("short description", text: $shortDescription, onCommit: {gotoField(.keywords)})
                    .autocapitalization(.sentences)
                    .disableAutocorrection(false)
                    .keyboardType(.default)
                    .focused($focusedField, equals: .shorty)
                Text(longDescription)
                TextField("keywords", text: $keywords, onCommit: {gotoField(.title)})
                    .autocapitalization(.none)
                    .disableAutocorrection(true)
                    .keyboardType(.default)
                    .focused($focusedField, equals: .keywords)
            }
        }
    }
}

标签: formsanimationswiftui

解决方案


推荐阅读