Ich erstelle eine App in Swift UI und Swift 6 für iOS 26. Ich verwende SwiftData zum Speichern von Inhalten. Ich habe ein Bearbeitungsblatt, mit dem ich Probleme habe.
Wenn das Blatt geladen wird, kann der Benutzer nicht auf das TextFeld tippen, um es sofort zu bearbeiten. Es sind mehrere Berührungen erforderlich, bis die Tastatur angezeigt wird. Dadurch wird der Text im Feld zum Ausschneiden, Kopieren und Einfügen hervorgehoben. Ich beschäftige mich seit Tagen damit und nutze sogar KI, um zu sehen, ob es helfen kann, aber ich komme nicht weiter.
Mein EditPolicyView.swift-Code:
Ich erstelle eine App in Swift UI und Swift 6 für iOS 26. Ich verwende SwiftData zum Speichern von Inhalten. Ich habe ein Bearbeitungsblatt, mit dem ich Probleme habe. Wenn das Blatt geladen wird, kann der Benutzer nicht auf das TextFeld tippen, um es sofort zu bearbeiten. Es sind mehrere Berührungen erforderlich, bis die Tastatur angezeigt wird. Dadurch wird der Text im Feld zum Ausschneiden, Kopieren und Einfügen hervorgehoben. Ich beschäftige mich seit Tagen damit und nutze sogar KI, um zu sehen, ob es helfen kann, aber ich komme nicht weiter. Mein EditPolicyView.swift-Code: [code]// // EditPolicyView.swift // Policy Pal // // Created by Justin Erswell on 09/01/2026. //
import SwiftUI import SwiftData import PhotosUI
// Lightweight attachment summary - no binary data, just metadata for display struct AttachmentSummary: Identifiable, Sendable { let id: UUID let filename: String let mimeType: String let isExisting: Bool // true = already saved in SwiftData, false = newly added
var isPDF: Bool { mimeType == "application/pdf" }
// Init for existing attachments (extracted values, not the model itself) init(id: UUID, filename: String, mimeType: String, isExisting: Bool) { self.id = id self.filename = filename self.mimeType = mimeType self.isExisting = isExisting }
// Convenience init for new attachments init(id: UUID = UUID(), filename: String, mimeType: String) { self.id = id self.filename = filename self.mimeType = mimeType self.isExisting = false } }
// Simple value struct to pass data without SwiftData observation // NOTE: Attachments are NOT copied here to avoid blocking main thread with large binary data struct EditPolicyData: Identifiable { let id: PersistentIdentifier var name: String var category: PolicyCategory var provider: String var policyNumber: String var cost: Decimal var costFrequency: CostFrequency var renewalDate: Date var notes: String var reminderThirtyDays: Bool var reminderFourteenDays: Bool var reminderThreeDays: Bool var reminderRenewalDay: Bool
init(from policy: PolicyItem) { let start = CFAbsoluteTimeGetCurrent() self.id = policy.persistentModelID print("⏱️ EditPolicyData: persistentModelID took \(CFAbsoluteTimeGetCurrent() - start)s")
// Actual form view with inline @State initialization (like AddPolicyView) struct EditPolicyFormView: View { @Environment(\.dismiss) private var dismiss @Environment(\.modelContext) private var modelContext @EnvironmentObject private var appSettings: AppSettings
// Store the policy ID for saving let policyID: PersistentIdentifier
// Initial values passed in let initialName: String let initialCategory: PolicyCategory let initialProvider: String let initialPolicyNumber: String let initialCost: Decimal let initialCostFrequency: CostFrequency let initialRenewalDate: Date let initialNotes: String let initialReminderThirtyDays: Bool let initialReminderFourteenDays: Bool let initialReminderThreeDays: Bool let initialReminderRenewalDay: Bool
// Form state - using inline initialization like AddPolicyView @State private var name = "" @State private var category: PolicyCategory = .insurance @State private var provider = "" @State private var policyNumber = "" @State private var cost: Decimal = 0 @State private var costString = "" @State private var costFrequency: CostFrequency = .yearly @State private var renewalDate = Date() @State private var notes = ""
// Reminder schedule @State private var reminderThirtyDays = true @State private var reminderFourteenDays = true @State private var reminderThreeDays = true @State private var reminderRenewalDay = true
// Track if we've loaded initial values @State private var hasLoadedInitialValues = false
// Attachments - use lightweight summaries for display, track changes separately @State private var attachmentSummaries: [AttachmentSummary] = [] @State private var newAttachments: [Attachment] = [] // Newly added attachments (with data) @State private var deletedAttachmentIDs: Set = [] // IDs of existing attachments to delete @State private var attachmentsLoaded = false @State private var selectedPhotoItems: [PhotosPickerItem] = [] @State private var showingDocumentScanner = false @State private var showingFilePicker = false
@State private var showingValidationError = false @State private var validationErrorMessage = ""
private var reminderFooterText: String { isSubscription ? "You'll receive notifications at 9:00 AM before your billing date." : "You'll receive notifications at 9:00 AM on these days." }
// Load attachment METADATA only (not binary data) to avoid blocking main thread private func loadAttachments() async { guard !attachmentsLoaded else { return } let start = CFAbsoluteTimeGetCurrent() print("⏱️ loadAttachments: starting...")
// Use a background context to avoid blocking main thread let container = modelContext.container let policyIDCopy = policyID
// Fetch raw metadata as tuples (Sendable) from background let metadata: [(UUID, String, String)] = await Task.detached { let bgStart = CFAbsoluteTimeGetCurrent() let backgroundContext = ModelContext(container) guard let policy = backgroundContext.model(for: policyIDCopy) as? PolicyItem else { return [] } // Only access metadata properties, NOT the data property let result = policy.safeAttachments.map { ($0.id, $0.filename, $0.mimeType) } print("⏱️ loadAttachments background task took \(CFAbsoluteTimeGetCurrent() - bgStart)s") return result }.value
// Create summaries on main actor attachmentSummaries = metadata.map { AttachmentSummary(id: $0.0, filename: $0.1, mimeType: $0.2, isExisting: true) } attachmentsLoaded = true print("⏱️ loadAttachments: TOTAL took \(CFAbsoluteTimeGetCurrent() - start)s") }
// MARK: - Save Changes private func saveChanges() { guard !name.trimmingCharacters(in: .whitespaces).isEmpty else { validationErrorMessage = "Please enter a name." showingValidationError = true return }
// Fetch the policy by ID guard let policy = modelContext.model(for: policyID) as? PolicyItem else { validationErrorMessage = "Could not find record to update." showingValidationError = true return }
// MARK: - Attachment Handling private func removeAttachment(_ summary: AttachmentSummary) { attachmentSummaries.removeAll { $0.id == summary.id } if summary.isExisting { // Mark existing attachment for deletion on save deletedAttachmentIDs.insert(summary.id) } else { // Remove newly added attachment newAttachments.removeAll { $0.id == summary.id } } }
private func processScannedImages(_ images: [UIImage]) { for (index, image) in images.enumerated() { if let data = image.jpegData(compressionQuality: 0.8) { let id = UUID() let filename = "scan_\(attachmentSummaries.count + index + 1).jpg" let mimeType = "image/jpeg"
// Add to newAttachments (with data) for saving let attachment = Attachment(filename: filename, data: data, mimeType: mimeType) attachment.id = id newAttachments.append(attachment)
private func processSelectedPhotos(_ items: [PhotosPickerItem]) { for item in items { Task { if let data = try? await item.loadTransferable(type: Data.self) { await MainActor.run { let id = UUID() let filename = "photo_\(attachmentSummaries.count + 1).jpg" let mimeType = "image/jpeg"
// Add to newAttachments (with data) for saving let attachment = Attachment(filename: filename, data: data, mimeType: mimeType) attachment.id = id newAttachments.append(attachment)
if let data = try? Data(contentsOf: url) { let id = UUID() let filename = url.lastPathComponent let mimeType = url.pathExtension.lowercased() == "pdf" ? "application/pdf" : "image/jpeg"
// Add to newAttachments (with data) for saving let attachment = Attachment(filename: filename, data: data, mimeType: mimeType) attachment.id = id newAttachments.append(attachment)
#Preview { EditPolicyView(policy: PolicyItem( name: "Test Policy", category: .insurance, provider: "Test Provider", renewalDate: Date() )) .modelContainer(for: PolicyItem.self, inMemory: true) .environmentObject(AppSettings.shared) } [/code] Außerdem ein Screenshot der Ansicht, die auf einem iPhone 17 Pro Max ausgeführt wird: [img]https://i.sstatic.net/CnhqP4rk.png[/img]
Ich bin mir sicher, dass ich etwas äußerst Dummes mache und wäre für die Hilfe der Community dabei dankbar.
Ich erstelle eine App in Swift UI und Swift 6 für iOS 26. Ich verwende SwiftData zum Speichern von Inhalten. Ich habe ein Bearbeitungsblatt, mit dem ich Probleme habe.
Wenn das Blatt geladen wird,...
Ich habe ein Projekt entwickelt. Ich bin mit einigen Problemen hinsichtlich der Reaktionsfähigkeit der Seite auf dem Handy konfrontiert. Kann mir bitte jemand weiterleiten, wie man sich verbessert?...
Ich habe ein Projekt entwickelt. Ich bin mit einigen Problemen hinsichtlich der Reaktionsfähigkeit der Seite auf dem Handy konfrontiert. Kann mir bitte jemand weiterleiten, wie man sich verbessert?...
Ich habe ein Projekt entwickelt. Ich bin mit einigen Problemen hinsichtlich der Reaktionsfähigkeit der Seite auf dem Handy konfrontiert. Kann mir bitte jemand weiterleiten, wie man sich verbessert?...
Ich habe die PIP-Installation für Twilio gemacht und das Terminal hat den größten Teil der Installation durchgeführt, aber am Ende gab es mir im Installationsfehlercode:
ERROR: Could not install...