From 53b90dc646f11bb8ce80412acce9239bd98d515a Mon Sep 17 00:00:00 2001 From: cheykrym Date: Sun, 5 Oct 2025 02:59:55 +0300 Subject: [PATCH] fix register close --- yobble/Views/Login/LoginView.swift | 2 +- yobble/Views/Login/RegistrationView.swift | 248 +++++++++++----------- 2 files changed, 123 insertions(+), 127 deletions(-) diff --git a/yobble/Views/Login/LoginView.swift b/yobble/Views/Login/LoginView.swift index d7c15b3..ebedcb7 100644 --- a/yobble/Views/Login/LoginView.swift +++ b/yobble/Views/Login/LoginView.swift @@ -124,7 +124,7 @@ struct LoginView: View { } .padding(.top, 10) .sheet(isPresented: $isShowingRegistration) { - RegistrationView(viewModel: viewModel) + RegistrationView(viewModel: viewModel, isPresented: $isShowingRegistration) } Spacer() diff --git a/yobble/Views/Login/RegistrationView.swift b/yobble/Views/Login/RegistrationView.swift index 43a83f0..7ab000b 100644 --- a/yobble/Views/Login/RegistrationView.swift +++ b/yobble/Views/Login/RegistrationView.swift @@ -9,6 +9,7 @@ import SwiftUI struct RegistrationView: View { @ObservedObject var viewModel: LoginViewModel + @Binding var isPresented: Bool @Environment(\.presentationMode) private var presentationMode @State private var username: String = "" @@ -40,149 +41,138 @@ struct RegistrationView: View { var body: some View { NavigationView { - ScrollView { - ZStack { + ZStack(alignment: .top) { Color.clear .contentShape(Rectangle()) - .onTapGesture { - hideKeyboard() - } + .onTapGesture { hideKeyboard() } - VStack(alignment: .leading, spacing: 16) { - - Group { - - HStack { - TextField(NSLocalizedString("Логин", comment: "Логин"), text: $username) - .autocapitalization(.none) - .disableAutocorrection(true) - Spacer() - if !username.isEmpty { - Image(systemName: isUsernameValid ? "checkmark.circle" : "xmark.circle") - .foregroundColor(isUsernameValid ? .green : .red) + VStack(alignment: .leading, spacing: 16) { + Group { + HStack { + TextField(NSLocalizedString("Логин", comment: "Логин"), text: $username) + .autocapitalization(.none) + .disableAutocorrection(true) + Spacer() + if !username.isEmpty { + Image(systemName: isUsernameValid ? "checkmark.circle" : "xmark.circle") + .foregroundColor(isUsernameValid ? .green : .red) + } } - } - .padding() - .background(Color(.secondarySystemBackground)) - .cornerRadius(8) - .autocapitalization(.none) - .disableAutocorrection(true) - .onChange(of: username) { newValue in - if newValue.count > 32 { - username = String(newValue.prefix(32)) - } - } - - if !isUsernameValid && !username.isEmpty { - Text(NSLocalizedString("Логин должен быть от 3 до 32 символов (английские буквы, цифры, _)", comment: "Логин должен быть от 3 до 32 символов (английские буквы, цифры, _)")) - .foregroundColor(.red) - .font(.caption) - } - - HStack { - SecureField(NSLocalizedString("Пароль", comment: "Пароль"), text: $password) - .autocapitalization(.none) - Spacer() - if !password.isEmpty { - Image(systemName: isPasswordValid ? "checkmark.circle" : "xmark.circle") - .foregroundColor(isPasswordValid ? .green : .red) - } - } - .padding() - .background(Color(.secondarySystemBackground)) - .cornerRadius(8) - .autocapitalization(.none) - .onChange(of: password) { newValue in - if newValue.count > 32 { - password = String(newValue.prefix(32)) - } - } - - if !isPasswordValid && !password.isEmpty { - Text(NSLocalizedString("Пароль должен быть от 8 до 128 символов", comment: "Пароль должен быть от 6 до 32 символов")) - .foregroundColor(.red) - .font(.caption) - } - - HStack { - SecureField(NSLocalizedString("Подтверждение пароля", comment: "Подтверждение пароля"), text: $confirmPassword) - .autocapitalization(.none) - Spacer() - if !confirmPassword.isEmpty { - Image(systemName: isConfirmPasswordValid ? "checkmark.circle" : "xmark.circle") - .foregroundColor(isConfirmPasswordValid ? .green : .red) - } - } - .padding() - .background(Color(.secondarySystemBackground)) - .cornerRadius(8) - .autocapitalization(.none) - .onChange(of: confirmPassword) { newValue in - if newValue.count > 32 { - confirmPassword = String(newValue.prefix(32)) - } - } - - if !isConfirmPasswordValid && !confirmPassword.isEmpty { - Text(NSLocalizedString("Пароли не совпадают", comment: "Пароли не совпадают")) - .foregroundColor(.red) - .font(.caption) - } - - TextField(NSLocalizedString("Инвайт-код (необязательно)", comment: "Инвайт-код"), text: $inviteCode) .padding() .background(Color(.secondarySystemBackground)) .cornerRadius(8) .autocapitalization(.none) .disableAutocorrection(true) - } + .onChange(of: username) { newValue in + if newValue.count > 32 { + username = String(newValue.prefix(32)) + } + } - Button(action: registerUser) { - if isLoading { - ProgressView() + if !isUsernameValid && !username.isEmpty { + Text(NSLocalizedString("Логин должен быть от 3 до 32 символов (английские буквы, цифры, _)", comment: "Логин должен быть от 3 до 32 символов (английские буквы, цифры, _)")) + .foregroundColor(.red) + .font(.caption) + } + + HStack { + SecureField(NSLocalizedString("Пароль", comment: "Пароль"), text: $password) + .autocapitalization(.none) + Spacer() + if !password.isEmpty { + Image(systemName: isPasswordValid ? "checkmark.circle" : "xmark.circle") + .foregroundColor(isPasswordValid ? .green : .red) + } + } + .padding() + .background(Color(.secondarySystemBackground)) + .cornerRadius(8) + .autocapitalization(.none) + .onChange(of: password) { newValue in + if newValue.count > 32 { + password = String(newValue.prefix(32)) + } + } + + if !isPasswordValid && !password.isEmpty { + Text(NSLocalizedString("Пароль должен быть от 8 до 128 символов", comment: "Пароль должен быть от 6 до 32 символов")) + .foregroundColor(.red) + .font(.caption) + } + + HStack { + SecureField(NSLocalizedString("Подтверждение пароля", comment: "Подтверждение пароля"), text: $confirmPassword) + .autocapitalization(.none) + Spacer() + if !confirmPassword.isEmpty { + Image(systemName: isConfirmPasswordValid ? "checkmark.circle" : "xmark.circle") + .foregroundColor(isConfirmPasswordValid ? .green : .red) + } + } + .padding() + .background(Color(.secondarySystemBackground)) + .cornerRadius(8) + .autocapitalization(.none) + .onChange(of: confirmPassword) { newValue in + if newValue.count > 32 { + confirmPassword = String(newValue.prefix(32)) + } + } + + if !isConfirmPasswordValid && !confirmPassword.isEmpty { + Text(NSLocalizedString("Пароли не совпадают", comment: "Пароли не совпадают")) + .foregroundColor(.red) + .font(.caption) + } + + TextField(NSLocalizedString("Инвайт-код (необязательно)", comment: "Инвайт-код"), text: $inviteCode) .padding() - .frame(maxWidth: .infinity) - .background(Color.gray.opacity(0.6)) - .cornerRadius(8) - } else { - Text(NSLocalizedString("Зарегистрироваться", comment: "Зарегистрироваться")) - .foregroundColor(.white) - .padding() - .frame(maxWidth: .infinity) - .background(isFormValid ? Color.blue : Color.gray.opacity(0.6)) + .background(Color(.secondarySystemBackground)) .cornerRadius(8) + .autocapitalization(.none) + .disableAutocorrection(true) } + + Button(action: registerUser) { + if isLoading { + ProgressView() + .padding() + .frame(maxWidth: .infinity) + .background(Color.gray.opacity(0.6)) + .cornerRadius(8) + } else { + Text(NSLocalizedString("Зарегистрироваться", comment: "Зарегистрироваться")) + .foregroundColor(.white) + .padding() + .frame(maxWidth: .infinity) + .background(isFormValid ? Color.blue : Color.gray.opacity(0.6)) + .cornerRadius(8) + } + } + .disabled(!isFormValid) + .padding(.bottom) } - .disabled(!isFormValid) - .padding(.bottom) - } - .padding() - } - .navigationBarItems(trailing: - Button(action: { - presentationMode.wrappedValue.dismiss() - }) { - Text(NSLocalizedString("Закрыть", comment: "Закрыть")) - } - ) - .navigationTitle(Text(NSLocalizedString("Регистрация", comment: "Регистрация"))) - .alert(isPresented: $showError) { - Alert( - title: Text(NSLocalizedString("Ошибка регистрация", comment: "Ошибка")), - message: Text(errorMessage), - dismissButton: .default(Text(NSLocalizedString("OK", comment: ""))) - ) + .padding() } } - .onTapGesture { - hideKeyboard() + .navigationTitle(Text(NSLocalizedString("Регистрация", comment: "Регистрация"))) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: dismissSheet) { + Text(NSLocalizedString("Закрыть", comment: "Закрыть")) + } + } + } + .alert(isPresented: $showError) { + Alert( + title: Text(NSLocalizedString("Ошибка регистрация", comment: "Ошибка")), + message: Text(errorMessage), + dismissButton: .default(Text(NSLocalizedString("OK", comment: ""))) + ) + } } - } - .onTapGesture { - hideKeyboard() } - } private func registerUser() { isLoading = true @@ -190,7 +180,7 @@ struct RegistrationView: View { viewModel.registerUser(username: username, password: password, invite: inviteCode.isEmpty ? nil : inviteCode) { success, message in isLoading = false if success { - presentationMode.wrappedValue.dismiss() + dismissSheet() } else { errorMessage = message ?? NSLocalizedString("Неизвестная ошибка.", comment: "") showError = true @@ -198,6 +188,12 @@ struct RegistrationView: View { } } + private func dismissSheet() { + hideKeyboard() + isPresented = false + presentationMode.wrappedValue.dismiss() + } + private func hideKeyboard() { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } @@ -208,6 +204,6 @@ struct RegistrationView_Previews: PreviewProvider { static var previews: some View { let viewModel = LoginViewModel() viewModel.isLoading = false // чтобы убрать спиннер - return RegistrationView(viewModel: viewModel) + return RegistrationView(viewModel: viewModel, isPresented: .constant(true)) } }