<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Creston</title>
    <description>The latest articles on DEV Community by James Creston (@creston).</description>
    <link>https://dev.to/creston</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1590683%2F036bdd09-3883-4564-a6a3-53d8d73e9a3f.jpeg</url>
      <title>DEV Community: James Creston</title>
      <link>https://dev.to/creston</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/creston"/>
    <language>en</language>
    <item>
      <title>SwiftUI .toolbar not showing at bottom of screen</title>
      <dc:creator>James Creston</dc:creator>
      <pubDate>Fri, 07 Jun 2024 12:23:43 +0000</pubDate>
      <link>https://dev.to/creston/swiftui-toolbar-not-showing-at-bottom-of-screen-48n1</link>
      <guid>https://dev.to/creston/swiftui-toolbar-not-showing-at-bottom-of-screen-48n1</guid>
      <description>&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;I have been following tutorials for a while and just cannot get past this bug that doesn’t generate any errors. &lt;/p&gt;

&lt;p&gt;I may have my .toolbar embedded is the wrong area of my View Controller. &lt;/p&gt;

&lt;p&gt;But my tool bar refuses to show at the bottom of the screen. &lt;/p&gt;

&lt;p&gt;See the two screen shots. One shows the toolbar but the report title and select button are not at the stop of the screen. &lt;/p&gt;

&lt;p&gt;The other is where I fixed the select/edit button but now the toolbar is missing. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


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&amp;lt;Int&amp;gt;()

    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: &amp;gt;) {
            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)
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;`&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9i22io6l8u53zxtlz6x9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9i22io6l8u53zxtlz6x9.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi6ki7yl5el23e6wfuxv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi6ki7yl5el23e6wfuxv.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>help</category>
    </item>
  </channel>
</rss>
