Hello, new coder here learning SwiftUI for the first time. Started an iOS coding journey this year after having not coded since 2005 when I last coded a social media website using html, css, and cold fusion7.
I have been following tutorials for a while and just cannot get past this bug that doesn’t generate any errors.
I may have my .toolbar embedded is the wrong area of my View Controller.
But my tool bar refuses to show at the bottom of the screen.
See the two screen shots. One shows the toolbar but the report title and select button are not at the stop of the screen.
The other is where I fixed the select/edit button but now the toolbar is missing.
import SwiftUI
import PhotosUI
struct ReportDetailView: View {
@Binding var report: Report
@State private var showPhotoLibrary = false
@State private var showCamera = false
@State private var selectedImages: [UIImage] = []
@State private var selectedImage: UIImage?
@State private var selectedImageIndex: Int?
@State private var showEditCaption = false
@State private var showEmailSheet = false
@State private var isSelecting = false
@State private var selectedPhotos = Set<Int>()
var body: some View {
VStack {
TextField("Report Title", text: Binding(
get: { report.title ?? "" },
set: { report.title = $0 }
))
.font(.largeTitle)
.padding(.top)
.background(Color.clear)
.frame(maxWidth: .infinity, alignment: .leading)
.textInputAutocapitalization(.words)
.onTapGesture {
self.dismissKeyboard()
}
.padding(.horizontal)
if report.photos.isEmpty {
Text("No Photos")
.foregroundColor(.gray)
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
} else {
ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 100))]) {
ForEach(report.photos.indices, id: \.self) { index in
VStack {
if let photo = report.photos[index].image {
Image(uiImage: photo)
.resizable()
.aspectRatio(contentMode: .fit)
.onTapGesture {
if isSelecting {
if selectedPhotos.contains(index) {
selectedPhotos.remove(index)
} else {
selectedPhotos.insert(index)
}
} else {
selectedImage = report.photos[index].image
selectedImageIndex = index
showEditCaption = true
}
}
.overlay(
isSelecting ?
Circle()
.stroke(selectedPhotos.contains(index) ? Color.blue : Color.clear, lineWidth: 3)
.frame(width: 30, height: 30)
.padding(5)
.background(Color.white.opacity(0.7).clipShape(Circle()))
.padding()
: nil
)
}
Text(report.photos[index].caption)
.font(.caption)
}
}
}
}
}
}
.navigationBarItems(trailing: Button(action: {
isSelecting.toggle()
selectedPhotos.removeAll()
}) {
Text(isSelecting ? "Cancel" : "Edit")
})
.toolbar {
ToolbarItem(placement: .bottomBar) {
HStack {
if isSelecting {
Button(action: deleteSelectedPhotos) {
Image(systemName: "trash")
.foregroundColor(.red)
}
Spacer()
}
Button(action: { showPhotoLibrary = true }) {
Image(systemName: "photo.on.rectangle.angled")
}
Spacer()
Button(action: { showCamera = true }) {
Image(systemName: "camera")
}
Spacer()
Button(action: { showEmailSheet = true }) {
Image(systemName: "envelope")
}
}
}
}
.sheet(isPresented: $showPhotoLibrary) {
UnifiedPicker(pickerType: .photoLibrary(single: false), selectedImages: $selectedImages)
.onDisappear {
for image in selectedImages {
if let imageData = image.jpegData(compressionQuality: 1.0) {
report.photos.append(Photo(imageData: imageData, caption: ""))
}
}
selectedImages.removeAll()
}
}
.sheet(isPresented: $showCamera) {
UnifiedPicker(pickerType: .camera, selectedImages: $selectedImages)
.onDisappear {
if let image = selectedImages.first, let imageData = image.jpegData(compressionQuality: 1.0) {
report.photos.append(Photo(imageData: imageData, caption: ""))
}
selectedImages.removeAll()
}
}
.sheet(isPresented: $showEditCaption) {
if let selectedIndex = selectedImageIndex {
EditCaptionView(photo: $report.photos[selectedIndex])
}
}
.sheet(isPresented: $showEmailSheet) {
if let emailData = emailData {
MailComposeViewController(mailData: emailData)
}
}
}
private func deleteSelectedPhotos() {
for index in selectedPhotos.sorted(by: >) {
report.photos.remove(at: index)
}
selectedPhotos.removeAll()
isSelecting.toggle()
}
private func dismissKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
private var emailData: Data? {
return PDFGenerator.generatePDF(for: report)
}
}
struct ReportDetailView_Previews: PreviewProvider {
@State static var report = Report(title: "Sample Report", date: Date(), photos: [])
static var previews: some View {
ReportDetailView(report: $report)
}
}
Top comments (4)
Hey, great post!
It will help a lot if you would format the first half of the code too! 🙌
Thank you for the feed back, let me try again and let me know if it’s corrected.
Thank you for the help, now I just need someone to assist with the bug in my code. Lol