【问题标题】:Scroll up to see TextField when the keyboard appears in SwiftUI当键盘出现在 SwiftUI 中时向上滚动以查看 TextField
【发布时间】:2020-01-18 08:47:24
【问题描述】:

在我的用例中,我必须在List 中的可用项目下方放置一个TextField,通过使用该TextField,我们可以将项目添加到List。

最初,没有列表项(items 数组为空)

这是一个最小的、可重现的示例

import SwiftUI

struct ContentView: View {
    @State var itemName = ""
    @State var items = [String]()

    var body: some View {
        NavigationView {
            List {
                ForEach(self.items, id: \.self) {
                    Text($0)
                }

                VStack {
                    TextField("Item Name", text: $itemName)
                        .textFieldStyle(RoundedBorderTextFieldStyle())

                    Button(action: {
                        self.items.append(self.itemName)
                        self.itemName = ""

                    }) {
                        Text("Add Item")
                    }
                }
            }
        .navigationBarTitle(Text("Title"))
        }
    }
}

我们可以通过在TextField 中输入一些内容并单击“添加项目”Button 向列表中添加一个新项目,我们使用TextField 添加的每个项目都显示在文本字段上方在List。所以TextField 在List 中下降(就像Apple 的提醒应用程序一样)。

如果应用程序有很多项目(超过 7 个项目),当键盘出现时,键盘会覆盖TextField,我们看不到TextField。
检查此屏幕截图:

我想知道的是如何在键盘出现时自动滚动列表(向上移动视图)以查看TextField(如在 Apple 的提醒应用中)。

【问题讨论】:

标签: swiftui swiftui-list


【解决方案1】:

我在最近的项目中遇到了类似的问题,解决它的最简单方法是将 UITextField 包装在 SwiftUI 中,然后从我的自定义包装器到达父滚动视图并告诉它在键盘出现时滚动。我在您的项目上尝试了我的方法,它似乎有效。

如果你从这个 GitHub 文件夹中获取包装器和其他文件的代码:https://github.com/LostMoa/SwiftUI-Code-Examples/tree/master/ScrollTextFieldIntoVisibleRange,然后用我的自定义视图 (TextFieldWithKeyboardObserver) 替换 SwiftUI TextField,那么它应该会滚动。

import SwiftUI

struct ContentView: View {
    @State var itemName = ""
    @State var items = [String]()

    var body: some View {
        NavigationView {
            List {
                ForEach(self.items, id: \.self) {
                    Text($0)
                }

                VStack {
                    TextFieldWithKeyboardObserver(text: $itemName, placeholder: "Item Name")

                    Button(action: {
                        self.items.append(self.itemName)
                        self.itemName = ""

                    }) {
                        Text("Add Item")
                    }
                }
            }
        .navigationBarTitle(Text("Title"))
        }
    }
}

我最近写了一篇文章解释了这个解决方案:https://lostmoa.com/blog/ScrollTextFieldIntoVisibleRange/

【讨论】:

  • 非常感谢!很好的答案和很棒的文章。我认为 SwiftUI 需要一种更好的方法来处理这个问题,在此之前,我认为包装 UIKitTextField 是最好的方法——尝试了很多解决方案。再次感谢!
  • 这是迄今为止使用 List 或 ScrollView 处理 UITextField 的最佳答案,我已经使用您的方法将 UITextView 向上移动,同时用户键入 UITextView 高度扩展(不滚动)的位置到输入的文字
  • 好主意!博文也不错。
  • 我正在尝试使用此解决方案,因为它运行良好,但使用自定义文本字段会禁用您可以调用常规文本字段的所有其他 swiftui 方法,例如 .keyboardType()、multilineTextAlignment()、等等。有没有办法解决这个问题?
  • 这是最好的解决方案,应该标记为接受的答案
猜你喜欢
  • 2019-10-22
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
相关资源
最近更新 更多