// // ChatView.swift // Chat // // Created by Sergey Tarasov on 24.07.2022. // import SwiftUI extension CGFloat { static let sidePadding: CGFloat = 14 } struct ChatView: View, KeyboardReadable { @State private var isKeyboardVisible = false @State var message: String = "" @State var messages: [String] = ["Display a short text message, called an alert, that draws attention to something new in your app.", "Play a notification sound.", "Set a badge number on the app’s icon to let the user know there are new items.", "Provide actions the user can take without opening the app.", "Show a media attachment.", "Be silent, allowing the app to perform a task in the background.", "No", "Group notifications into threads.", "Yes", "Edit or remove delivered notifications.", "Run code to change your notification before displaying it.", "Display a custom, interactive UI for your notification.", "And probably more.", "Yes", "Edit or remove delivered notifications.", "Run code to change your notification before displaying it.", "Display a custom, interactive UI for your notification.", "And probably more."] var body: some View { VStack(alignment: .center, spacing: 0) { ScrollView { ScrollViewReader { value in VStack { withAnimation { ForEach(messages.indices, id: \.self) { i in HStack { if messages[i] == messages[3] || messages[i] == messages[6] || messages[i] == messages[8] || i > 17{ Spacer() MessageView(text: messages[i], time: "23:03", isSelf: true) } else { MessageView(text: messages[i], time: "23:03", isSelf: false) Spacer() } } } .onChange(of: messages) { _ in withAnimation { value.scrollTo(messages.count - 1, anchor: .bottomTrailing) } } .onReceive(keyboardPublisher) { newIsKeyboardVisible in isKeyboardVisible = newIsKeyboardVisible withAnimation { value.scrollTo(messages.count - 2, anchor: .topTrailing) } } .onAppear { value.scrollTo(messages.count - 1, anchor: .top) } } } .padding(.horizontal, .sidePadding) .padding(.vertical, 12) .background(Color.indigo.opacity(0.0)) } } Divider() HStack { TextField("Сообщение", text: $message) .textFieldStyle(.automatic) .padding(.vertical, 6) .padding(.horizontal, 12) .background(.background) Button { messages.append(message) message = "" } label: { Image(systemName: "arrow.up.circle.fill") .font(.title) .foregroundColor(message.isEmpty ? .gray : .accentColor) } .disabled(message.isEmpty) } .padding(.horizontal, .sidePadding) .padding(.vertical, 6) .background() } .navigationBarTitleDisplayMode(.inline) } } struct ChatView_Previews: PreviewProvider { static var previews: some View { Group { NavigationView { ChatView() } NavigationView { ChatView() .preferredColorScheme(.dark) } } } }