Skip to content

Instantly share code, notes, and snippets.

@1amageek
Last active February 1, 2022 07:42
Show Gist options
  • Save 1amageek/5c26ac882d643584b45cb0b1996b0d0f to your computer and use it in GitHub Desktop.
Save 1amageek/5c26ac882d643584b45cb0b1996b0d0f to your computer and use it in GitHub Desktop.
Message UI Sample Code
//
// ContentView.swift
// Message
//
// Created by 1amageek on 2022/02/01.
//
import SwiftUI
struct Transcript: Identifiable, Codable, Hashable {
var id: String
var message: String
var timestamp: Date
init(id: String = UUID().uuidString, message: String, timestamp: Date = Date()) {
self.id = id
self.message = message
self.timestamp = timestamp
}
}
struct ContentView: View {
@State var transcripts: [Transcript] = []
@State var contentSize: CGSize = .zero
@State var text: String = ""
var sortedTranscripts: [Transcript] {
transcripts.sorted(by: { $0.timestamp < $1.timestamp })
}
var body: some View {
Group {
if transcripts.isEmpty {
VStack {
Spacer()
Text("🥺")
.font(.system(size: 120))
Text("Empty")
.bold()
.foregroundColor(.secondary)
.font(.system(size: 32))
Spacer()
}
} else {
GeometryReader { screen in
ScrollViewReader { proxy in
ScrollView {
VStack {
Spacer()
LazyVStack {
ForEach(sortedTranscripts) { transcript in
HStack {
Spacer()
Text(transcript.message)
.padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
.background(Color(.systemGray5))
.cornerRadius(16)
.id(transcript.id)
}
.padding(.horizontal, 8)
}
}
.background {
GeometryReader { vstack in
let _ = print(vstack.size)
EmptyView()
.onChange(of: vstack.size) { newValue in
self.contentSize = newValue
}
}
}
}
.frame(height: self.contentSize.height >= screen.size.height ? nil : screen.size.height)
}
.frame(width: screen.size.width, height: screen.size.height)
.onChange(of: sortedTranscripts) { transcripts in
if let transcript = transcripts.last {
withAnimation { proxy.scrollTo(transcript.id) }
}
}
}
}
}
}
.safeAreaInset(edge: .bottom) {
HStack(alignment: .bottom) {
TextEditor(text: $text)
.frame(minHeight: 32)
.fixedSize(horizontal: false, vertical: true)
.cornerRadius(12)
Button {
let transcript = Transcript(message: text)
withAnimation {
self.transcripts.append(transcript)
self.text = ""
}
} label: {
Image(systemName: "arrow.up.circle.fill")
.resizable()
.padding(4)
.frame(width: 32, height: 32)
.contentShape(Circle())
}
.disabled(text.isEmpty)
}
.padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
.background(.bar)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment