Post

Replies

Boosts

Views

Activity

External Keyboard DatePicker Issues
I am currently trying to get my app ready for full external keyboard support, while testing I found an issue with the native DatePicker. Whenever I enter the DatePicker with an external keyboard it only jumps to the time picker and I am not able to move away from it. Arrow keys don't work, tab and control + tab only move me to the toolbar and back. This is how they look like private var datePicker: some View { DatePicker( "", selection: date, in: minDate..., displayedComponents: [.date] ) .fixedSize() .accessibilityIdentifier("\(datePickerLabel).DatePicker") } private var timePicker: some View { DatePicker( "", selection: date, in: minDate..., displayedComponents: [.hourAndMinute] ) .fixedSize() .accessibilityIdentifier("\(datePickerLabel).TimePicker") } private var datePickerLabelView: some View { Text(datePickerLabel.localizedString) .accessibilityIdentifier(datePickerLabel) } And we implement it like this in the view: HStack { datePickerLabelView Spacer() datePicker timePicker } Does anyone know how to fix this behavior? Is it our fault or is it the system? The issue comes up both in iOS 18 and 26.
0
1
16
2h
SwiftUI Main Actor Isolation Error with PhotosPicker
I'm getting the following error in my SwiftUI code: "Main actor-isolated property 'avatarImage' can not be referenced from a Sendable closure" I don't understand how to fix it. This happens in the following code: You can copy-paste this into an empty project and make sure to have Swift 6 enabled under the Build Settings > Swift Language Version import PhotosUI import SwiftUI public struct ContentView: View { @State private var avatarItem: PhotosPickerItem? @State private var avatarImage: Image? @State private var avatarData: Data? public var body: some View { VStack(spacing: 30) { VStack(alignment: .center) { PhotosPicker(selection: $avatarItem, matching: .images) { if let avatarImage { avatarImage .resizable() .aspectRatio(contentMode: .fill) .frame(width: 100, height: 100) .foregroundColor(.gray) .background(.white) .clipShape(Circle()) .opacity(0.75) .overlay { Image(systemName: "pencil") .font(.title) .shadow(radius: 5) } } else { Image(systemName: "person.circle.fill") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 100, height: 100) .foregroundColor(.gray) .background(.white) .clipShape(Circle()) .opacity(0.75) .overlay { Image(systemName: "pencil") .font(.title) .shadow(radius: 5) } } } } } .onChange(of: avatarItem) { Task { if let data = try? await avatarItem?.loadTransferable( type: Data.self ) { if let processed = processImage(data: data) { avatarImage = processed.image avatarData = processed.data } else { } } } } } private func processImage(data: Data) -> (image: Image?, data: Data?)? { guard let uiImage = UIImage(data: data)?.preparingForDisplay() else { return nil } // Check original size let sizeInMB = Double(data.count) / (1024 * 1024) // If image is larger than 1MB, compress it if sizeInMB > 1.0 { guard let compressedData = uiImage.compress() else { return nil } return (Image(uiImage: uiImage), compressedData) } return (Image(uiImage: uiImage), data) } } #Preview { ContentView() } public extension UIImage { func compress(to maxSizeInMB: Double = 1.0) -> Data? { let maxSizeInBytes = Int( maxSizeInMB * 1024 * 1024 ) // Convert MB to bytes var compression: CGFloat = 1.0 let step: CGFloat = 0.1 var imageData = jpegData(compressionQuality: compression) while (imageData?.count ?? 0) > maxSizeInBytes, compression > 0 { compression -= step imageData = jpegData(compressionQuality: compression) } return imageData } }
1
0
606
Feb ’25