У меня есть макет, показанный ниже, со списком и текстовым полем в VStack (интерфейс, похожий на чат).
struct ContentView: Просмотр { @State var input: String = "" var body: some View { VStack(выравнивание: .center) { List ((1...40), id: \.self) { индекс в строка (дляИндекс: индекс) .padding(.дно) .listRowSeparator(.скрытый) .listRowInsets(.init()) } .listStyle(.plain) TextField("Ввод", текст: $input) .padding(.init(верхнее: 0, ведущее: 15, нижнее: 0, завершающее: 15)) .foregroundColor(.blue) .textFieldStyle(RoundedBorderTextFieldStyle.init()) } } func row (forIndex index: Int) -> some View { Текст("# \(индекс)") .frame(maxWidth: .infinity) .background(index % 2 == 0 ? .yellow : .green ) } } У меня возникла проблема, когда список прокручивается в самый низ и отображается программная клавиатура. В тот момент, когда клавиатура начинает появляться на экране, весь контекст списка мгновенно перемещается вниз на значение, равное высоте TextField. См. прикрепленный gif.
В некоторой степени это имеет смысл, поскольку TextField учитывает безопасную область клавиатуры и поэтому перемещается вверх вместе с клавиатурой. Но похоже, что в то же время List расширяется на пространство, занимаемое ранее TextView.
Но как избежать этого «скачка» содержимого списка? Это определенно как-то связано с безопасной зоной. Я пробовал играть с такими свойствами, как .ignoresSafeArea, но безуспешно.
При использовании ScrollView с VStack или LazyVStack такого эффекта нет, но по некоторым причинам мне приходится придерживаться List.< /п>

Изменить: я пробовал предоставить TextField как пользовательский safeAreaInset, это устраняет проблему с отображением клавиатуры, но есть еще один сбой, когда клавиатура скрыта, аналогично содержимое перемещается. слишком уж до дна.
var body: some View { List ((1...40), id: \.self) { индекс в строка (дляИндекс: индекс) .padding(.дно) .listRowSeparator(.скрытый) .listRowInsets(.init()) } .listStyle(.plain) .safeAreaInset(edge: .bottom) { TextField("Ввод", текст: $input) .padding(.init(верхнее: 0, ведущее: 15, нижнее: 0, завершающее: 15)) .foregroundColor(.blue) .textFieldStyle(RoundedBorderTextFieldStyle.init()) } }
Мобильная версия