Skip to content

Instantly share code, notes, and snippets.

@tobitech
Created March 2, 2025 21:30
Show Gist options
  • Save tobitech/cc808a3f834075a00f7dc6ab035460d2 to your computer and use it in GitHub Desktop.
Save tobitech/cc808a3f834075a00f7dc6ab035460d2 to your computer and use it in GitHub Desktop.
Messages PhotoPicker
import PhotosUI
import SwiftUI
// Attempt to replicate the behaviour of the photos picker with the text input field and keyboard area in the iOS 18 Messages app.
struct MessagesPhotosPickerView: View {
@State private var text: String = ""
@State private var showPhotosPicker: Bool = false
@State private var photoItem: PhotosPickerItem?
var body: some View {
NavigationStack {
VStack {
ScrollView(.vertical) {
MessagesList()
}
.scrollDismissesKeyboard(.interactively)
Spacer()
MessageInput()
}
.sheet(isPresented: $showPhotosPicker) {
PhotosPicker(selection: $photoItem) {}
.photosPickerStyle(.inline)
.photosPickerDisabledCapabilities([.collectionNavigation, .search])
.presentationDetents([.height(336), .large])
.presentationBackground(.clear)
.presentationBackgroundInteraction(.enabled(upThrough: .large))
}
}
}
@ViewBuilder
func MessagesList() -> some View {
ForEach(0..<10, id: \.self) { index in
HStack(alignment: .top) {
VStack(alignment: .leading) {
Text("Sender \(index + 1)")
Text("Message \(index + 1)")
.font(.subheadline)
.foregroundStyle(.secondary)
}
Spacer()
Text(Date().formatted(date: .abbreviated, time: .omitted))
.font(.subheadline)
}
.padding(.vertical, 5)
.padding(.horizontal)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
@ViewBuilder
func MessageInput() -> some View {
HStack {
Button {
// UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
showPhotosPicker = true
} label: {
Image(systemName: "plus.circle.fill")
.font(.title)
.foregroundStyle(.tertiary)
}
.buttonStyle(.plain)
HStack(alignment: .bottom) {
TextField(
"iMessage",
text: $text,
axis: .vertical
)
.lineLimit(10)
Button {
} label: {
Image(systemName: "arrow.up.circle.fill")
.font(.title2)
}
.tint(.primary)
.disabled(text.isEmpty)
}
.padding(.vertical, 5)
.padding(.horizontal, 10)
.background(.regularMaterial, in: .rect(cornerRadius: 30))
}
.padding(.horizontal, 10)
.padding(.bottom, 10)
}
}
#Preview {
MessagesPhotosPickerView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment