Проверено только на симуляторе. Я нашел код для прокрутки VStack, когда будет отображаться клавиатура
, но я получаю ошибку precondition failure: invalid input index: 4
Изображение прикреплено
Я загрузил video .
import SwiftUI
import Combine
struct AdaptsToKeyboard: ViewModifier {
@State var currentHeight: CGFloat = 0
func body(content: Content) -> some View {
GeometryReader { geometry in
content
.padding(.bottom, self.currentHeight)
.animation(.easeOut(duration: 0.16))
.onAppear(perform: {
NotificationCenter.Publisher(center: NotificationCenter.default, name: UIResponder.keyboardWillShowNotification)
.merge(with: NotificationCenter.Publisher(center: NotificationCenter.default, name: UIResponder.keyboardWillChangeFrameNotification))
.compactMap { notification in
notification.userInfo?["UIKeyboardFrameEndUserInfoKey"] as? CGRect
}
.map { rect in
rect.height - geometry.safeAreaInsets.bottom
}
.subscribe(Subscribers.Assign(object: self, keyPath: \.currentHeight))
NotificationCenter.Publisher(center: NotificationCenter.default, name: UIResponder.keyboardWillHideNotification)
.compactMap { notification in
CGFloat.zero
}
.subscribe(Subscribers.Assign(object: self, keyPath: \.currentHeight))
})
}
}
}
Вот как я использую этот модификатор:
struct LoginView: View {
@State private var email = ""
@State var showWelcomeView = false
@State var loopAnimation = false
var body: some View {
NavigationView {
ZStack {
Color.customLightGray
if self.loopAnimation {
VStack {
LottieView(named: "19451-blue-preloader",
loop: self.loopAnimation,
size: 200
).padding(.top, 350)
.padding(.leading, 110)
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
} else {
VStack (alignment: .leading, spacing: 10) {
Text("Email:")
.font(.headline)
TextField("Enter your email", text: $email)
.padding(.all)
.font(Font.system(size: 18, weight: .medium, design: .rounded))
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.blue, lineWidth: 1))
.foregroundColor(Color.blue)
.keyboardType(.emailAddress)
.autocapitalization(.none)
Button(action: {
}) {
Text("Forgot password?")
.fontWeight(.bold)
.font(.headline)
.padding(EdgeInsets(top: 20, leading: 10, bottom: 20, trailing: 0))
.foregroundColor(.blue)
}
HStack {
Button(action: {
}) {
Text("Create account")
.fontWeight(.bold)
.font(.subheadline)
.padding()
.foregroundColor(.blue)
}
Spacer()
Button(action: {
self.loopAnimation.toggle()
self.fetchUser(with: self.email)
}) {
Text("Next")
.fontWeight(.bold)
.font(.title)
.padding(EdgeInsets(top: 20, leading: 40, bottom: 20, trailing: 40))
.background(Color.blue)
.cornerRadius(8)
.foregroundColor(.white)
}
NavigationLink(destination: WelcomeView(), isActive: $showWelcomeView) { EmptyView() }
}
}.padding(.horizontal, 30)
.modifier(AdaptsToKeyboard())
}
}
.navigationBarTitle(Text("Login"))
.edgesIgnoringSafeArea(.all)
}
}
func fetchUser(with email: String) {
UserService().getUser(with: email) { (user) in
self.loopAnimation = false
self.showWelcomeView = true
}
}
}
struct LoginView_Previews: PreviewProvider {
static var previews: some View {
LoginView()
}
}
, если я удаляю условие if self.loopAnimation
, тогда мой код работает хорошо без такого SIGABRT