Я создаю интерфейс в стиле чата с помощью SwiftUI с TextField внизу и List элементов над ним. Когда текстовое поле получает фокус и появляется клавиатура, поле и его фон не остаются прикрепленными к клавиатуре, а перемещаются немного вперед или назад. Вот пример:
Это было сделано с помощью safeAreaInset:
struct ContentView: View {
@State private var message = ""
var body: some View {
List([Color.red, .orange, .yellow, .green, .blue, .indigo, .purple], id: \.self) { color in
color
.frame(height: 150)
.listRowInsets(EdgeInsets())
}
.scrollContentBackground(.hidden)
.safeAreaInset(edge: .bottom) {
TextField("Chat", text: $message)
.textFieldStyle(.roundedBorder)
.padding()
.background(.thinMaterial)
}
}
}
Я получаю аналогичные результаты, располагая их в VStack:
var body: some View {
VStack(spacing: 0) {
List([Color.red, .orange, .yellow, .green, .blue, .indigo, .purple], id: \.self) { color in
color
.frame(height: 150)
.listRowInsets(EdgeInsets())
}
.scrollContentBackground(.hidden)
TextField("Chat", text: $message)
.textFieldStyle(.roundedBorder)
.padding()
.background(.thinMaterial)
}
}
Время анимации не было бы большой проблемой, если бы фон за текстовым полем во время анимации распространялся на клавиатуру. Пробовал сделать это с помощью ignoresSafeArea(.all, edges: .bottom), но видимого эффекта это не дало.
Я обнаружил, что превосходный Callsheet Кейси Лисса нашел способ сделать это (он упомянул, что использовал SwiftUI для приложения), но я не уверен, как это сделать. Вот как выглядит Callsheet при наличии клавиатуры:
Кто-нибудь знает, как добиться такого поведения?
В демонстрациях использовались Xcode 15.4 и iOS 17.5. Я получаю тот же результат, используя Xcode 16 beta 6 с iOS 18. Поведение непоследовательное, но постоянное. Клавиатура движется довольно быстро, поэтому это кратковременно (но очень раздражает). Включите медленную анимацию, чтобы ее было легче увидеть.
Вы уверены, что настоящий разрыв вызван не .scrollContentBackground(.hidden)? Кроме того, подтвердили ли вы, что это происходит и на реальных устройствах. Симуляторы иногда...
Модификатор scrollContentBackground предназначен только для того, чтобы скрыть другую ошибку пользовательского интерфейса — описанное мной поведение все равно произойдет, если вы его удалите. И да, вы получаете то же самое на устройстве (используя iOS 17.5 на телефоне — у вас нет под рукой устройства iOS 18, но маловероятно, что это будет разница).
Те из вас, кто заключает опечатку: почему? Использование ShapeStyle вместо представления, требующего ViewModifier, не является опечаткой!





Заставлять TextField точно соответствовать анимации клавиатуры бесполезно, поскольку можно использовать сторонние клавиатуры или другие подобные замены клавиатуры, которые имеют собственную анимацию представления.
Вместо этого вы правы, если хотите, чтобы фон был представлен после TextField. Вы упоминаете, что пытались сделать это с помощью ignoresSafeArea, но безрезультатно, но не указываете, где именно вы это пробовали в коде, что наводит меня на мысль, что это просто было привязано к неправильному представлению.
Представление, в котором вы хотите игнорировать безопасную область клавиатуры, — это именно фон. В вашем случае это тонкий материал. Поэтому материалу необходимо игнорировать безопасную зону.
ThinMaterial — это ShapeStyle, а не View, поэтому модификаторы ViewModifiers нельзя применять напрямую.
Вместо этого создайте представление самостоятельно и примените модификатор.
struct ContentView: View {
…
var body: some View {
…
.safeAreaInset(edge: .bottom) {
TextField("Chat", text: $message)
…
.background {
Rectangle().fill(.thinMaterial).edgesIgnoringSafeArea(.all)
}
}
}
}
Когда нижняя безопасная область расширяется вверх за счет клавиатуры, фон позади нее представляет собой тонкий материал.
Как вы говорите, я прикрепил расширение безопасной зоны к неправильному виду. Очень признателен за помощь. Однако есть одна небольшая поправка — вместо устаревшего edgesIgnoringSafeArea я бы рекомендовал ignoresSafeArea(.all, edges: .bottom).
Я не могу воспроизвести это на iOS 17.4 (или, возможно, мои глаза просто плохо видят быстро движущиеся объекты). Какую версию iOS вы используете?