Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

Posts under SwiftUI tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Bug in .onmove for SwiftData models
I modified the default Items example from xcode to include two models, a view with a query and a detail view. On this detail view I cannot properly move all items, only the top two, please see the attached video. Especially strange is that some dragging does work and some does not. It changes with the number of sub-items on a todo. The models are SwiftData and it is have a one-to-many relationship. On the many relationship the problem exists. How should the code be adjusted to make sure all items are draggable? https://imgur.com/a/n1y7iXX Below is all code necessary for the minimal example. I target iOS 17.5 and this shows on both preview, simulator and my iPhone. Models @Model final class ToDo { var timestamp: Date var items: [Item] init(timestamp: Date) { self.timestamp = timestamp self.items = [] } } @Model final class Item { var timestamp: Date var done: Bool init(timestamp: Date, done: Bool) { self.timestamp = timestamp self.done = done } } ItemListView (Here is the problem!) struct ItemListView: View { @Bindable var todo: ToDo var body: some View { List { ForEach($todo.items) { $item in Text(item.timestamp.description) } .onMove { indexSet, offset in todo.items.move(fromOffsets: indexSet, toOffset: offset) } } } } ContentView struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query var items: [ToDo] var body: some View { NavigationSplitView { List { ForEach(items) { item in NavigationLink { ItemListView(todo: item) } label: { Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard)) } } .onDelete(perform: deleteItems) } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { EditButton() } ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } detail: { Text("Select an item") } } private func addItem() { withAnimation { let newItem = ToDo(timestamp: Date()) modelContext.insert(newItem) } } private func deleteItems(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(items[index]) } } } } APP @main struct ListProjectApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([ ToDo.self, ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { return try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } }() var body: some Scene { WindowGroup { ContentView() } .modelContainer(ToDoContainer.create()) } } actor ToDoContainer { @MainActor static func create() -> ModelContainer { let schema = Schema([ ToDo.self, Item.self ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) let container = try! ModelContainer(for: schema, configurations: [modelConfiguration]) let todo = ToDo(timestamp: Date()) container.mainContext.insert(todo) let item1 = Item(timestamp: Date(), done: false) let item2 = Item(timestamp: Date(), done: false) let item3 = Item(timestamp: Date(), done: false) todo.items.append(item1) todo.items.append(item2) todo.items.append(item3) return container } }
1
0
92
15h
HELP ME!!
I'm studying Swift programing with using Apple official document "Develop in Swift Tutorial" https://developer.apple.com/tutorials/develop-in-swift/. When I do that, I faced to some problems which I cannot resolve myself. So, could you help or advise me about it. Problem:I can't implement this program which this below text say. How do I write the code?? (This section is that "Wrap-up: Lists and Text fields, Develop in Swift Tutorials") Here's my current states... import SwiftUI struct ContentView: View { @State private var names: [String] = [] @State private var nameToAdd = "" @State private var pickedName = "" @State private var shouldRemovePickedName = false var body: some View { VStack { VStack(spacing: 8) { Image(systemName: "person.3.sequence.fill") .foregroundStyle(.tint) .symbolRenderingMode(.hierarchical) Text("Pick-a-Pal") } .font(.title) .bold() //3項条件演算子 Text(pickedName.isEmpty ? "" : pickedName) .font(.title2) .bold() .foregroundStyle(.tint) List { ForEach(names, id: \.self) { name in Text(name) } } .clipShape(RoundedRectangle(cornerRadius: 8)) TextField("Add Name", text: $nameToAdd) //単語の自動修正をオフにする .autocorrectionDisabled() .onSubmit { if !nameToAdd.isEmpty { names.append(nameToAdd) nameToAdd = "" } } Divider() Toggle("Remove when picked", isOn: $shouldRemovePickedName) Button { if let randomName = names.randomElement() { pickedName = randomName if shouldRemovePickedName { names.removeAll() { name in return (name == randomName) } } } else { pickedName = "" } } label: { Text("Pick Random Name") .padding(.vertical, 8) .padding(.horizontal, 16) } .buttonStyle(.borderedProminent) .font(.title2) } .padding() } } #Preview { ContentView() }
1
0
70
7h
SwiftUI Trap change of orientation
The real truth is that I don't know what I am doing. I am trying to trap the change of orientation event. I have been strongly advised to use "Size Classes" rather than "Landscape" or "Portrait". Apparently, this is what Apple recommends. I have tried two or three ways to do this, and my closest effort to get it working has run me into an Issue (code below) that I don't know how to solve. I believe I have to use the @Evinroment macros to pick up the current size classes (@Environment(\.horizontalSizeClas) var .... and @Environment(\.verticalSizeClass) var ....) and these have to go inside a "View", I think. But I know when I get to setting up the Notification Center I will have to use the @Published macro to pass the orientation value back to my main "ContentView", again I think. And the @Published macro needs to run in a class. So I have tried to put a "View" inside a "class" and run into an issue that the @Pulished variable (a String) is only recognised in the "class" and the size classes are only recognised in the "View". So How do I overcome this? Here is the Code I have come up with so far, it is incomplete and when I get this working I will add more. import SwiftUI final class OrientChange { @Published public var myOrient: String init(myOrient: String){ self.myOrient = myOrient } struct SizeClassView: View { @Environment(\.horizontalSizeClass) var myHorizClass: UserInterfaceSizeClass? @Environment(\.verticalSizeClass) var myVertClass: UserInterfaceSizeClass? var body: some View { Text("Horiz Class: \(myHorizClass)") if myHorizClass == .compact && myVertClass == .regular { OrientChange.myOrient = "Portrait" } else { Text("No") } } } } #Preview { OrientChange.SizeClassView() }
2
0
120
1d
View is not updating by adding or deleting an item
When I parse the query result(SwiftData) to my DetailView it works fine. But when I delete the item in the DetailView the view isn't updated. I parse the array from the dataModel to the DetailView. But I do not understand why it's not updating when I add or delete a tree in the DetailView. Only when I append the tree to the array from the other model after insert it works. Does someone have a tip for me? Here is my Code: https://gist.github.com/romanindermuehle/14441c21f689e91b26942d997f75300d
0
0
100
2d
protocol in swiftUI
I've been reading the documentation and apparently protocols force structures, classes or enumerations to implement specific methods or define certain variables. I've double checked this functionality by typing the following code. In fact, xcode compiler helped me to verify this since it popped up an alert that depicted the following message : "Type MiguelStruc does not conform to protocol Miguels ..." protocol Miguels { func someF()-> Float } public struct MiguelStruc{ var miguelVar : String = "hey" } extension MiguelStruc: Miguels{ } Now, while I was following the official swiftUI drawing paths and shapes tutorial I encountered this particular chain of code: (https://developer.apple.com/tutorials/swiftui/drawing-paths-and-shapes) Path { path in } .fill(.black) By diving into the Swiftui documentation I noticed that Shape is a protocol public protocol Shape : Sendable, Animatable, View which is implemented by the Path structure extension Path : Shape Why none of the Path extensions content are explicitly implementing any of the Shape protocol requirements? such as role, layoutDirectionBehavior, sizeThatFits, offset, intersection, union, and so on!
3
0
139
1d
Picker from the toolbar in watchOS (SwiftUI)
What I'm trying to do is to display a picker in watchOS: this picker will have only 4 options, so I would like it to be in the style of .navigationLink. Currently I have this code inside a view and everything works fine (DateRange is an enum): Picker(selection: $dateRange) { Text("Today").tag(DateRange.today) Text("This week").tag(DateRange.thisWeek) Text("Last 7 days").tag(DateRange.lastSevenDays) Text("Last 30 days").tag(DateRange.lastThirtyDays) } label: { Image(systemName: "line.3.horizontal.decrease.circle") } .pickerStyle(.navigationLink) What I'd like to do is to move this picker to the toolbar: I've seen that by wrapping it in a ToolbarItem everything works, but the current selection is displayed in the toolbar button, and this breaks the layout (the string doesn't fit). Moreover, when the picker appears from the toolbar the options still work, but are grayed out, as if they were disabled. Is there a way to have a picker appear when clicking on a toolbar item, but not showing the selection and being "enabled"?
0
0
98
2d
SwiftUI Orientation Change
I have been struggling for nearly a week to handle orientation changes. In a previous post https://developer.apple.com/forums/thread/755957 I was strongly advised to use Size Classes, and I am trying to do that. by following this post: https://forums.developer.apple.com/forums/thread/126878) But I still can get it to work, so far I am just trying to initialize all the variables I will use later on. please bear with me I am 65 and have not done any coding for coming for 40 years. This my latest effort: import SwiftUI final class myOrientationChange: ObservableObject { @Published var myOrient: String = "" @Environment(\.verticalSizeClass) var myVertClass: UserInterfaceSizeClass? @Environment(\.horizontalSizeClass) var myHorizClass: UserInterfaceSizeClass? var _observer: NSObjectProtocol? if myHorizClass == .compact && myVertClass == .regular { self.myOrient = "Portrait" } elseif myHorizClass == .regular && myVertClass == .compact { self.myOrient = "Landscape" } else { self.myOrient = "Something Else" } } struct ContentView: View { @EnvironmentObject var envOrient: myOrientationChange var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") Text("Orientation is \(envOrient.myOrient)") } .padding() } } #Preview { ContentView() } I will go on to use the NotificationCenter to trap there change of orientation even. On the line if myHorizClass == ......... It tells me "Expected declaration in declaration of 'myOrientChange'" What have I done wrong?
1
0
134
2d
"Unexpectedly found nil while unwrapping an Optional value" in URL
Before anyone rants and raves about checking documentation - I have spent the last 4 hours trying to solve this issue on my own before asking for help. Coding in Swift is VERY new for me and I'm banging my head against the wall trying to teach myself. I am very humbly asking for help. If you refer me to documentation, that's fine but I need examples or it's going to go right over my head. Teaching myself is hard, please don't make it more difficult. I have ONE swift file with everything in it. import Foundation import Cocoa import Observation class GlobalString: ObservableObject { @Published var apiKey = "" @Published var link = "" } struct ContentView: View { @EnvironmentObject var globalString: GlobalString var body: some View { Form { Section(header: Text("WallTaker for macOS").font(.title)) { TextField( "Link ID:", text: $globalString.link ) .disableAutocorrection(true) TextField( "API Key:", text: $globalString.apiKey ) .disableAutocorrection(true) Button("Take My Wallpaper!") { } } .padding() } .task { await Wallpaper().fetchLink() } } } @main struct WallTaker_for_macOSApp: App { @AppStorage("showMenuBarExtra") private var showMenuBarExtra = true @EnvironmentObject var globalString: GlobalString var body: some Scene { WindowGroup { ContentView() .environmentObject(GlobalString()) } // MenuBarExtra("WallTaker for macOS", systemImage: "WarrenHead.png", isInserted: $showMenuBarExtra) { // Button("Refresh") { //// currentNumber = "1" // } // Button("Love It!") { //// currentNumber = "2" // } // Button("Hate It!") { //// currentNumber = "3" // } // Button("EXPLOSION!") { // // currentNumber = "3" // } //// // } } } class Wallpaper { var url: URL? = nil var lastPostUrl: URL? = nil let mainMonitor: NSScreen init() { mainMonitor = NSScreen.main! } struct LinkResponse: Codable { var post_url: String? var set_by: String? var updated_at: String } struct Link { var postUrl: URL? var setBy: String var updatedAt: Date } func parseIsoDate(timestamp: String) -> Date? { let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" return formatter.date(from: timestamp) } func fetchLink() async { do { url = URL(string: GlobalString().link) let (data, _) = try await URLSession.shared.data(from: url!) let decoder = JSONDecoder() let linkResponse = try decoder.decode(LinkResponse.self, from: data) let postUrl: URL? = linkResponse.post_url != nil ? URL(string: linkResponse.post_url!) : nil let date = parseIsoDate(timestamp: linkResponse.updated_at) let link = Link( postUrl: postUrl, setBy: linkResponse.set_by ?? "anon", updatedAt: date ?? Date() ) try update(link: link) } catch { } } func update(link: Link) throws { guard let newPostUrl = link.postUrl else { return } if (newPostUrl != lastPostUrl) { lastPostUrl = newPostUrl let tempFilePath = try getTempFilePath() try downloadImageTo(sourceURL: newPostUrl, destinationURL: tempFilePath) try applyWallpaper(url: tempFilePath) } else { } } private func applyWallpaper(url: URL) throws { try NSWorkspace.shared.setDesktopImageURL(url, for: mainMonitor, options: [:]) } private func getTempFilePath() throws -> URL { let directory = NSTemporaryDirectory() let fileName = NSUUID().uuidString let fullURL = NSURL.fileURL(withPathComponents: [directory, fileName])! return fullURL } private func downloadImageTo(sourceURL: URL, destinationURL: URL) throws { let data = try Data(contentsOf: sourceURL) try data.write(to: destinationURL) } } The 'fetchLink' function is where things explode, specifically when setting the URL. I do not know what I'm doing wrong.
3
0
156
3d
SwiftUI: How do I tell when my device orientation changes
Sorry to repeat this, but the new style forum won't allow me access to the original version of this question, and the answers. I have been searching the internet for 3 or 4 days now to find only complex solutions that I cannot get working. All I want to do is determine when the device orientation changes so that I can update the background Image. This is what I have so far: Import SwiftUI struct Main_Menu_iPhone: View { @State private var bloodGlucose: Float = 0.0 var body: some View { ZStack { Image("iPhone Background Portrait 828 x 1792 ") .resizable() .aspectRatio(contentMode: .fill) VStack { HStack { Label("Blood Glucose", systemImage: "drop.fill") TextField("Blood Glucose : ", value: $bloodGlucose, format: .number) .onSubmit() { print("Your Blood Gluse is : \(bloodGlucose)") } .background(.white) .frame(alignment: .topTrailing) Spacer() } Spacer() }.padding(.top, 250) } } }
1
0
277
4d
SwiftUI: How do I detect a change in device orientation?
Please can someone help I have spent 3 - 4 days trawling the internet and only finding complex answers that I can't get to work, and my head is ready to explode. I only want to detect when the device orientation has changed and load a different background image. This is what I have so far: import SwiftUI struct Main_Menu_iPhone: View { @State private var bloodGlucose: String = "0.0" var body: some View { ZStack { Image("iPhone Background Portrait 828 x 1792 ") .resizable() .aspectRatio(contentMode: .fill) VStack { TextField("Blood Glucose : ", text: $bloodGlucose) Spacer() } } } } #Preview { Main_Menu_iPhone() }
2
0
176
5d
Get Touch Events from iOS keyboard trackpad mode
Hello, As of iOS 17, the keyboard app runs in a different process. I was wondering if there is a way to access the UIView of the keyboard app or if there is a way to subscribe to touch events done on the keyboard (especially during the trackpad mode). By trackpad mode I mean when the user long presses on space and then can move in the keyboard area (that turns into a trackpad) to move the caret in a text. Either Objective C or SwiftUI is fine. Thanks!
1
0
108
4d
glassMaterialEffect not working in immersive view with a skybox
I seem to be running into an issue where the .glassBackgroundEffect modifier doesn't seem to render correctly. The issue is occurring when attached to a view shown in a RealityKit immersive view with a Skybox texture. The glass effect is applied but doesn't let any of the colour of the skybox behind it though. I have created a sample project which is just the immersive space template with the addition of a skybox texture and an attachment with the glassBackgroundEffect modifier. The RealityView itself is struct ImmersiveView: View { var body: some View { RealityView { content, attachments in // Add the initial RealityKit content if let immersiveContentEntity = try? await Entity(named: "Immersive", in: realityKitContentBundle) { content.add(immersiveContentEntity) let attachment = attachments.entity(for: "foo")! let leftSphere = immersiveContentEntity.findEntity(named: "Sphere_Left")! attachment.position = [0, 0.2, 0] leftSphere.addChild(attachment) // Add an ImageBasedLight for the immersive content guard let resource = try? await EnvironmentResource(named: "ImageBasedLight") else { return } let iblComponent = ImageBasedLightComponent(source: .single(resource), intensityExponent: 0.25) immersiveContentEntity.components.set(iblComponent) immersiveContentEntity.components.set(ImageBasedLightReceiverComponent(imageBasedLight: immersiveContentEntity)) // Put skybox here. See example in World project available at var skyboxMaterial = UnlitMaterial() let skyboxTexture = try! await TextureResource(named: "pano") skyboxMaterial.color = .init(texture: .init(skyboxTexture)) let skyboxEntity = Entity() skyboxEntity.components.set(ModelComponent(mesh: .generateSphere(radius: 1000), materials: [skyboxMaterial])) skyboxEntity.scale *= .init(x: -1, y: 1, z: 1) content.add(skyboxEntity) } } update: { _, _ in } attachments: { Attachment(id: "foo") { Text("Hello") .font(.extraLargeTitle) .padding(48) .glassBackgroundEffect() } } } } The effect is shown bellow I've tried this both in the simulator and in a physical device and get the same behaviour. Not sure if this is an issue with RealityKit or if I'm just holding it wrong, would greatly appreciate any help. Thanks.
1
0
129
4d
How to get selected usdz model thumbnail image using QuickLookThumbnailing
I am doing below code for getting thumbnail from usdz model using the QuickLookThumbnailing, But don't get the proper out. guard let url = Bundle.main.url(forResource: resource, withExtension: withExtension) else{ print("Unable to create url for resource.") return } let request = QLThumbnailGenerator.Request(fileAt: url, size: size, scale: 10.0, representationTypes: .all) let generator = QLThumbnailGenerator.shared generator.generateRepresentations(for: request) { thumbnail, type, error in DispatchQueue.main.async { if thumbnail == nil || error != nil { print(error) }else{ let tempImage = Image(uiImage: thumbnail!.uiImage) print(tempImage) self.thumbnailImage = Image(uiImage: thumbnail!.uiImage) print("=============") } } } } Below Screen Shot for selected model : Below is the thumbnail image, which not come with guitar but get only usdz icon.
1
0
110
4d
Swiftui - Pressing button in a list also actions another button
List(am.students) { item in HStack { Text(item.name).font(fancyFont) Spacer() Button(item.casual ? "All Paid" : "Reverse All Paid") { // Issue: pressing this button also results in Remove button action being invoked. item.casual = !item.casual }.foregroundColor(Color(white: 0.15)) .padding(3) .overlay( RoundedRectangle(cornerRadius: 5) .stroke(Color(white: 0.5), lineWidth: 3) ) Spacer().frame(width: 40) Button("Remove") { Task { await am.delete(student: item) } }.foregroundColor(Color(white: 0.15)) .frame(width: 80) .padding(3) .overlay( RoundedRectangle(cornerRadius: 5) .stroke(Color(white: 0.5), lineWidth: 3) ) } } When "All Paid" button is pressed, the "Remove" button action also executes. At a guess, the list row executes everything? Mark
2
0
131
5d
SwiftUI `onOpenURL` lacks `referrerURL` and `annotation` present in NSUserActivity
Hello, I am working on an application that utilizes both AppDelegate and SceneDelegate. We are looking to convert the top level app to SwiftUI and start using the SwiftUI App lifecycle. When implementing, I see that deep links when the app is backgrounded will only route to the onOpenURL modifier. This means that information we relied on before like referrerURL and annotation present in the NSUserActivity object delivered to the app is no longer available. Is there any work around for this? It seems like missing functionality because there is no way to route the deep links through AppDelegate or SceneDelegate if you are using the SwiftUI App protocol.
1
0
115
4d
View update issues + DisclosureGroup issue
My code was working perfectly well until the latest Xcode update. Suddenly the DisclosureGroup stopped working, causing the app to freeze. Also there seems to have been a change to the way SwiftUI tracks view updates because some of my code went into a screaming loop thinking a view was constantly changing. Developing code is hard enough without these problems coming out of nowhere.
1
0
89
3d
SwiftUI Menu
I want to use Menu in NavigationStack in my SwiftUI project. I found the menu list to wide - I want to use simple picture in the list. Menu{ ForEach(flagArray, id: .self) { name in Button { } label: { Image(name) // I want that the cell list will have maximum width 100 } } } label: { Image(name) .resizable() .frame(width: 40, height: 40) } I try to find a way to make it shorter. My .extension, MenuStyle, MenuCustomView didn't work. I found that you can hide it by simply .hidden! but how you can modify it? Please help
2
0
112
5d
How to get selected usdz model thumbnail image with material apply in vision os?
I want to get thumbnail image from USDZ model from vision os, But it will get image without material apply. Here is my code import Foundation import SceneKit import SceneKit.ModelIO class ARQLThumbnailGenerator { private let device = MTLCreateSystemDefaultDevice()! /// Create a thumbnail image of the asset with the specified URL at the specified /// animation time. Supports loading of .scn, .usd, .usdz, .obj, and .abc files, /// and other formats supported by ModelIO. /// - Parameters: /// - url: The file URL of the asset. /// - size: The size (in points) at which to render the asset. /// - time: The animation time to which the asset should be advanced before snapshotting. func thumbnail(for url: URL, size: CGSize, time: TimeInterval = 0) -> UIImage? { let renderer = SCNRenderer(device: device, options: [:]) renderer.autoenablesDefaultLighting = true if (url.pathExtension == "scn") { let scene = try? SCNScene(url: url, options: nil) renderer.scene = scene } else { let asset = MDLAsset(url: url) let scene = SCNScene(mdlAsset: asset) renderer.scene = scene } let image = renderer.snapshot(atTime: time, with: size, antialiasingMode: .multisampling4X) self.saveImageFileInDocumentDirectory(imageData: image.pngData()!) return image } func saveImageFileInDocumentDirectory(imageData : Data){ var uniqueID = UUID().uuidString let tempPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) let tempDocumentsDirectory: AnyObject = tempPath[0] as AnyObject let uniqueVideoID = uniqueID + "image.png" let tempDataPath = tempDocumentsDirectory.appendingPathComponent(uniqueVideoID) as String try? imageData.write(to: URL(fileURLWithPath: tempDataPath), options: []) } }
1
0
112
6d