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

SwiftUI Documentation

Posts under SwiftUI tag

2,339 Posts
Sort by:
Post marked as solved
3 Replies
144 Views
I have a driving tracking app I'm working on that properly starts tracking and logging location when the app is in the foreground or background. I use a buffer/queue to keep recent locations so when a trip ramps up to driving speed I can record that to work back to the start location just before the trip starts. This works great, however, in background mode when the user does not have the app open it will record locations but not until a significant location change is detected. The buffering I do is lost and the location only starts tracking several hundred yards or more after the trip has started. Does anyone have any suggestions or strategies to handle this chicken and the egg scenario?
Posted Last updated
.
Post not yet marked as solved
0 Replies
63 Views
Adding environment value openURL or dismiss to a View in a NavigationStack, without even using it, causes an infinite refresh loop. What doesn't work: a) struct ViewA: View { @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { ViewB() } } } struct ViewB: View { @Environment(\.openURL) var openURL var body: some View { NavigationLink("Next", value: 1) .navigationDestination(for: Int.self, destination: itemView) } func itemView(_ item: Int) -> some View { Text("Item \(item)") } } Prints ViewB: _openURL changed. infinitely. b) Passing the path to ViewB and appending the value with a Button What works: a) .navigationDestination(for: Int.self) { Text("Item \($0)") } Prints ViewB: @self, @identity, _openURL changed. ViewB: @self, _openURL changed. ViewB: _openURL changed. (3 times) b) Handling the destination on ViewA, which is not ideal for my use case. Prints ViewB: @self, @identity, _openURL changed. ViewB: _openURL changed. (5 times) While the workaround would work, it is still unclear how the environment value can cause the freeze (and eventual crash). Also that passing a function as parameter fails, while providing the destination in place does not. The code is stripped down to the minimal reproducible version. Any thoughts?
Posted
by takadeivi.
Last updated
.
Post marked as solved
2 Replies
99 Views
It is driving me crazy, because I really don't know what I am doing wrong. I have a observable class: @Observable class Variables: Identifiable { var id: UUID() var xValue: Int = 1 var yValue: Int = 1 } And a main view that calls a Subview to set the variables, using environment to set variables to the Subview, because this is a very simplified code example and in the final code lot more subview are gonna use this data. struct MainView: View { @State var vars = Variables() var body: Some View { VStack { Subview() .environment(vars) .padding() Text("Value X = \($vars.xValue)") Text("Value Y = \($vars.yValue)") } } struct Subview: View { @Environment(Variables.self) private var vars var body: Some View { VStack { TextField("xValue", value $vars.xValue, format: .number) { Text("X") } TextField("yValue", value $vars.yValue, format: .number) { Text("Y") } } } I Get this error for the TextFields: Cannot convert value of type 'Int' to expected argument type 'Binding' I just don't get it. Am I mixing up different kind of bindings, is something wrong in the definition of TextField.......................................... Please help me.
Posted
by SilkSound.
Last updated
.
Post not yet marked as solved
0 Replies
60 Views
In SwiftUI, a link is identified as both a button and link, this is during when running with VoiceOver. I know you can remove the button trait using .accessibilityRemoveTraits. However, I am sure there is a reason to it. Can somebody explain if it is genuinely a bug.
Posted
by Mayur123.
Last updated
.
Post not yet marked as solved
0 Replies
57 Views
Hello, I have a custom iOS app that takes a picture every second and uploads them to an S3 bucket. However, I was wondering if there is a way to send these images to a Mac instead via USB. Basically the app would capture a photo and send it directly to a location in Mac via USB. I couldn't find any good info online so I am not sure how realistic this is. Thanks a lot!
Posted
by gonn94.
Last updated
.
Post not yet marked as solved
1 Replies
139 Views
I need to create a carousel component with the following requirements (sorted by relevance): Objectives Every image is 16:9 aspect ratio and resizes to fit the screen. Needs a zoom and pan functionality, possibly the same way as iOS Photos app. Needs to work both in landscape and portrait mode, with a smooth transition between orientations. When orientation changes, the image needs to be rotated to preserve the center of the image (like Photos app and hyperoslo/Lightbox) The component should only take the minimum necessary space. In most use cases, such component should have other subviews both above and below. Circularity. I would like the carousel to wrap around. What I tried: Using a TabView with .tabViewStyle(PageTabViewStyle()).indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always)) modifiers. This didn't work: rotating the interface caused the view to get stuck between pages (it looks like it's a well known [bug]).(https://stackoverflow.com/questions/72435939/swiftui-tabview-is-not-working-properly-on-orientation-change). Implementing a single page (that is, an image view) using an UIScrollView and an UIViewRepresentable, then collecting them into an HStack. Unfortunately I need to use zoomScale and contentOffset properties of the UIScrollView outside of the UIViewRepresentable itself. The net result was that .init() was invoked for every image in the carousel at every rotation, causing severe stutters and an horrible rotation animation. Implementing the whole carousel using UIKit, and an UICollectionView, whose cells were an instance of UIScrollView. The problem is, the UIScrollView needs to recompute its constraints upon rotation but a cell is an instance of UIView, so it can't respond to rotations via viewWillTransition(to:CGSize, with: any UIViewControllerTransitionCoordinator). In the UICollectionView itself, you can only access the visible cells (one at a time is visible), and cells are cached, so even after rotating, some occasionally are presented on screen with the same appearance as before the rotation (some do, some don't, in the same UICollectionView). Also when rotating, it looks like the UIScrollView of the visible cell is being recreated, making it impossible to preserve the image center (I use this subclass of UIScrollView for this purpose). And the UICollectionView is taking the full window size, not just the bare minimum necessary space. Help: With all of this in mind, what options do I realistically have? If necessary I can raise the minimum iOS version to 16.0, even though I guess it doesn't make any significative difference since SwiftUI introduced MagnifyGesture only from iOS 17.0.
Posted Last updated
.
Post not yet marked as solved
1 Replies
162 Views
Hey folks, I need to implement a view for a live activity (so using. WidgetKit), so any UIKit/SceneKit is a non-starter. The thing to implement is a horizontal representation of a 360 degree protractor ('degree triangle'). I would like this view to be inifintely scrollable as if the user has a circular shape around their head and they can rotate their head to look at all the numbers, and when they reach 360/0, they simply continue with new round. In both directions. I've managed to get this working for the positive values by using a LazyHStack and which is populated using ForEach, using a custom class that implements RandomAccessCollection where the endIndex is Int.max (not truly infinite, but good enough). However, I can't get the scrollview/ForEach to start in the 'center' of the Int.max range (I'm sure this would cause some performance issue as well). So my question is: how to get a SwiftUI scrollview to behave like a infinite scrollview, pretty much like Josh Shaffer explained in WWDC 2011 in the session with Eliza Block called 'Advanced ScrollView Techniques'?
Posted
by Joride.
Last updated
.
Post not yet marked as solved
1 Replies
204 Views
Looking at having editable text as the detail view within a master detail interface. There are various examples out there that show how to build the NSViewRepresentable wrapper around NSTextView. e.g. https://developer.apple.com/forums/thread/125920 However, when I try to embed the NSViewRepresentable within a NavigationSplitView the various examples (and my own attempt) don't work properly. There seems to be a race condition competing to update the internal bindings. I also see updateNSView being called multiple times when only one event, say selection change, is called once. Using the SwiftUI TextEditor view actually works. (it is just so limited) When the master selected item is changed the change isn't automatically propagated through to update the Coordinator. That's because there isn't a delegate for "master did change". Take any of the TextViews on their own (not within a split view) and they work as you would expect. The SwiftUI TextEditor does this without any obvious connection to the master. So the first question is: has anybody solved this type of problem? I haven't yet found a link to the solution or a discussion on the internal trick to make this work. In principle the view structure is: NavigationSplitView { // master list List(selection : $selectedItem { } } content: { TextEditor(text: $selectedItem.text) // works // or CustomTextView(text: $selectedItem.text) // all examples I've found so far fail to properly display changes to the text when edited } My current thought is that the internal Coordinator needs to know that there has been a selection change so you can synchronise the significant change in the contents of the text binding. Again TextEditor doesn't need to know that. makeNSView is only called once, so there isn't any regeneration of the NSTextView that you could rely on. Have tried on both macOS and iOS and see the same results.
Posted
by purple.
Last updated
.
Post not yet marked as solved
1 Replies
113 Views
Hello everyone,I am a student who is working on my final project of my college.I do not get an official development account since I do not need to put my app on AppStore. In my project,I need to use the camera of iOS device, and I know I need to add NSCameraUsageDesciption in Info.plist.However, as I add the description in my Info and build my project, it failed and says"Provisioning profile "iOS Team Provisioning Profile: " doesn't include the NSCameraUsageDescription and NSPhotoLibraryUsageDescription entitlements." I also notice that in the Info.plist file, when I change the property type to entitlements,I just cannot find NSCameraUsageDescription when I add row. What's the problem?Is this because I am not an official developer?
Posted Last updated
.
Post not yet marked as solved
0 Replies
105 Views
If put a List in ScrollVIew, List won't appear: import SwiftUI struct BugView: View { let numbers: [Int] = [0, 1, 2] var body: some View { ScrollView { List(numbers, id: \.self) { number in Text(number.description) } } } } #Preview { BugView() }
Posted Last updated
.
Post not yet marked as solved
0 Replies
128 Views
I have a simple example to demonstrate... struct MyView: View { var body: some View { Text("WOW") } } struct MyOtherView: View { var body: some View { NavigationStack { Text("WOW") } } } On VisionOS, MyOtherView has a glass background effect that cannot be disabled. glassBackgroundEffect(displayMode: .never) .background(.clear), .foregroundColor(.clear), none of them work. I then resorted to the SwiftUIIntrospect package to try set .clear on various child objects of the NavigationStack but nothing is working. I am in control of my own glass containers. I have a couple with space between them, but with the NavigationStack it sets a background behind both of them ruining the effect. This is what MyOtherView renders as: I'm looking for it to be completely transparent except the text. Like the below layout. For now I will have to roll my own navigation.
Posted
by lbennett.
Last updated
.
Post not yet marked as solved
0 Replies
61 Views
When you run the following SwiftUI code, images unrelated to animation will flicker. import SwiftUI struct TestAnimationView: View { @State private var effectFlg = false private let imageName = "image1" @State var rotationDegrees = 0.0 var body: some View { VStack() { Text("Rectangle") Rectangle() .foregroundColor(.blue) .frame(width: 100, height: 100) .padding(.bottom, 30) Text("PNG Image") if let _imageName = Bundle.main.path(forResource: imageName, ofType: "png") { Image(uiImage: UIImage(contentsOfFile: _imageName)!) .resizable() .frame(width: 100, height: 100) .padding(.bottom, 30) } Text("PNG Image") if let _imageName = Bundle.main.path(forResource: imageName, ofType: "png") { Image(uiImage: UIImage(contentsOfFile: _imageName)!) .resizable() .frame(width: 100, height: 100) // .scaleEffect(self.effectFlg ? 1 : 0.8) .rotationEffect(.degrees(self.rotationDegrees)) } Spacer() Button("Start Animation") { withAnimation(.default.repeatForever().speed(0.5)) { if self.effectFlg { rotationDegrees = 0.0 } else { rotationDegrees = 360.0 } self.effectFlg.toggle() } } } } }
Posted
by POCO2002.
Last updated
.
Post not yet marked as solved
2 Replies
565 Views
This is my test code. import SwiftUI extension View { @MainActor func render(scale: CGFloat) -> UIImage? { let renderer = ImageRenderer(content: self) renderer.scale = scale return renderer.uiImage } } struct ContentView: View { @Environment(\.colorScheme) private var colorScheme @State private var snapImg: UIImage = UIImage() var snap: some View { Text("I'm now is \(colorScheme == .dark ? "DARK" : "LIGHT") Mode!") .foregroundStyle(colorScheme == .dark ? .red : .green) } @ViewBuilder func snapEx() -> some View { VStack { Text("@ViewBuilder I'm now is \(colorScheme == .dark ? "DARK" : "LIGHT") Mode!") .foregroundStyle(colorScheme == .dark ? .red : .green) Text("@ViewBuilder I'm now is \(colorScheme == .dark ? "DARK" : "LIGHT") Mode!") .background(.pink) Text("@ViewBuilder I'm now is \(colorScheme == .dark ? "DARK" : "LIGHT") Mode!") .background(.purple) Text("@ViewBuilder I'm now is \(colorScheme == .dark ? "DARK" : "LIGHT") Mode!") .foregroundStyle(colorScheme == .dark ? .red : .green) Text("@ViewBuilder I'm now is \(colorScheme == .dark ? "DARK" : "LIGHT") Mode!") .foregroundStyle(colorScheme == .dark ? .red : .green) } } @ViewBuilder func snapView() -> some View { VStack { Text("Text") Text("Test2") .background(.green) snap snapEx() } } var body: some View { let snapView = snapView() VStack { snapView Image(uiImage: snapImg) Button("Snap") { snapImg = snapView.render(scale: UIScreen.main.scale) ?? UIImage() } } } } When using ImageRenderer, there are some problems with converting View to images. For example, Text cannot automatically modify the foreground color of Dark Mode. This is just a simple test code, not just Text. How should I solve it?
Posted
by jBanana.
Last updated
.
Post not yet marked as solved
0 Replies
104 Views
I've been trying to follow the "Supporting Continuity Camera in Your Mac App" article to implement the "Import from iPhone or iPad" menu for my MacOS app. I've been able to replicate most of the article in a test AppKit application but cannot do the same in my SwiftUI application. I'm not sure how to get the "NSMenuItemImportFromDeviceIdentifier" identifier into a SwiftUI Menu or create a NSMenu with a NSMenuItem for a SwiftUI app. I'm also not sure how to handle receiving the image in the SwiftUI environment. Any advice you might have is appreciated. Thanks!
Posted Last updated
.
Post not yet marked as solved
0 Replies
99 Views
I am trying to create a near real-time drawing of waveform data from within a SwiftUI app. The data is streaming in from the hardware and I've verified that the draw(in ctx: CGContext) override in my custom CALayer is getting called. I have added this custom CALayer class as a sublayer to a UIView instance that I am making available via the UIViewRepresentable protocol. The only time I see updated output from the CALayer is when I rotate the device and layout happens (I assume). How can I force SwiftUI to update every time I render new data in my CALayer? More Info: I'm porting an app from the Windows desktop. Previously, I tried to make this work by simply generating a new UIImage from a CGContext every time I wanted to update the display. I quickly exhausted memory with that technique because a new context is being created every time I call UIGraphicsImageRenderer(size:).image { context in }. What I really wanted was something equivalent to a GDI WritableBitmap. Apparently this animal allows a programmer to continuously update and re-use the contents. I could not figure out how to do this in Swift without dropping down to the old CGBitmapContext stuff written in C and even then I wasn't sure if that would give me a reusable context that I could output in SwiftUI each time I refreshed it. CALayer seemed like the answer. I welcome any feedback on a better way to do what I'm trying to accomplish.
Posted Last updated
.
Post not yet marked as solved
1 Replies
124 Views
I was coding a sidebar on macOS and folded it with my mouse, but every time I run the app, I can't see the sidebar, so I can't use the sidebar. If you add a new image once, you can't see the same, but the third window also shows the sidebar well. I don't know why It's similar when you run it on another computer at all. Current code import CoreData struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @State private var isSidebarVisible: Bool = true var body: some View { NavigationView { if isSidebarVisible { Sidebar() } MemoListView().environment(\.managedObjectContext, viewContext) } .frame(minWidth: 700, minHeight: 400) .toolbar { ToolbarItem(placement: .navigation) { Button(action: toggleSidebar) { Image(systemName: "sidebar.leading") } } } } private func toggleSidebar() { withAnimation { isSidebarVisible.toggle() } } struct Sidebar: View { @Environment(\.managedObjectContext) private var viewContext var body: some View { List { NavigationLink(destination: EasyWebListView().environment(\.managedObjectContext, viewContext)) { Label("Web Links", systemImage: "link") } NavigationLink(destination: MemoListView().environment(\.managedObjectContext, viewContext)) { Label("Memos", systemImage: "note.text") } NavigationLink(destination: ThemeListView().environment(\.managedObjectContext, viewContext)) { Label("Themes", systemImage: "photo.on.rectangle.angled") } NavigationLink(destination: AccessView().environment(\.managedObjectContext, viewContext)) { Label("Access Records", systemImage: "clock.fill") } } .navigationTitle("My App") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) } } And the code used when there was a problem before. import CoreData struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @State private var isSidebarVisible: Bool = true var body: some View { NavigationView { Sidebar().environment(\.managedObjectContext, viewContext) MemoListView().environment(\.managedObjectContext, viewContext) } .frame(minWidth: 700, minHeight: 400) .toolbar { ToolbarItem(placement: .navigation) { Button(action: { withAnimation { isSidebarVisible.toggle() } }) { Image(systemName: "sidebar.leading") } } } } struct Sidebar: View { @Environment(\.managedObjectContext) private var viewContext var body: some View { List { NavigationLink(destination: EasyWebListView().environment(\.managedObjectContext, viewContext)) { Label("Web Links", systemImage: "link") } NavigationLink(destination: MemoListView().environment(\.managedObjectContext, viewContext)) { Label("Memos", systemImage: "note.text") } NavigationLink(destination: ThemeListView().environment(\.managedObjectContext, viewContext)) { Label("Themes", systemImage: "photo.on.rectangle.angled") } NavigationLink(destination: AccessView().environment(\.managedObjectContext, viewContext)) { Label("Access Records", systemImage: "clock.fill") } } .listStyle(SidebarListStyle()) .navigationTitle("My App") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) } }
Posted Last updated
.
Post not yet marked as solved
2 Replies
126 Views
I'm developing an application using SwiftUI and SwiftData. The app includes a pricing section, and I'd like it to have an initial default value for pricing. Additionally, when updating the app on the App Store, I also want to update the prices. However, I'd like users to have the option to create their own prices if they don't want to use the ones I suggest. I want to save these prices obtained from the user because I'll be using these values for some operations later on. I'm wondering how to achieve this. Should I use SwiftData or UserDefaults for managing the data, or should I save the prices to a JSON file? If I opt for saving to a JSON file, would it be possible to update the JSON file when updating the app? Please feel free to ask any questions. Thank you in advance for your responses.
Posted Last updated
.
Post not yet marked as solved
1 Replies
118 Views
Hi all apple devs! I am a young developer who is completely new to everything programming. I am currently trying to develop an app where I want to use visionkit, but I can't for the life of me figure out how to implement its features. I've been stuck on this for several days, so I am now resorting to asking all of you experts for help! Your assistance would be immensely appreciated! I started to develop the app trying to exclusively use swiftUI to futureproof my app. Upon figuring out what visionkit is, to my understanding it is more compatible with UIkit? So I rewrote the part of my code that will use visionkit into a UIkit based view, to simplify the integration of visionkits features. It might just have overcomplicated my code? Can visionkit be easily implemented using only swiftUI? I noticed in the demo on the video tutorial the code is in a viewcontroller not a contentview, is this what makes my image unresponsive? My image is not interactable like her demo in the video, where in my code do I go wrong? Help a noob out! The desired user flow is like this: User selects an image through the "Open camera" or "Open Camera Roll" buttons. Upon selection the UIkit based view opens and the selected image is displayed on it. (This is where I want to implement visionkit features) User interacts with the image by touching on it, if touching on a subject, the subject should be lifted out of the rest of the image and be assigned to the editedImage, which in turn displays only the subject without the background on the contentview. (For now the image is assigned to editedimage by longpressing without any subjectlifting since I cant get visionkit to work as I want) Anyways, here's a code snippet of my peculiar effort to implement subject lifting and visionkit into my app:
Posted
by emol.
Last updated
.
Post not yet marked as solved
1 Replies
136 Views
So I have a simple view for my SwiftUI application below: import SwiftUI struct ContentView: View { var body: some View { List { ForEach(0..<4) { index in RowView(index: index) .accessibilityIdentifier("row") } } } } struct RowView: View { let index: Int var body: some View { HStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") Spacer() ButtonView(index: index) } .padding() } } struct ButtonView: View { let index: Int var body: some View { VStack { if index != 3 { Button(action: {}, label: { Text("Cancel") }) .accessibilityIdentifier("cancel_button") } Button(action: {}, label: { Text("Submit") }) .accessibilityIdentifier("submit_button") } } } My goal is to reference each cancel and submit button per row for a UI Test, which I have tried doing so here: let rowElements = app.tables.cells.matching(identifier: "row") for i in 0..<rowElements.count { let cancelButton = rowElements.element(boundBy: i).buttons["cancel_button"] let submitButton = rowElements.element(boundBy: i).buttons["submit_button"] XCTAssertTrue(cancelButton.exists, "Cancel button does not exist in row \(i)") XCTAssertTrue(submitButton.exists, "Submit button does not exist in row \(i)") } Even with the identifiers set like this my tests fail and say it cannot find the buttons labeled as they are with their specific identifiers or the rows. What is the correct way to reference elements if they are in a list or table for UI Testing? I'm specifically trying to use accessibility Identifiers to make my life easy.
Posted
by matson.
Last updated
.
Post not yet marked as solved
1 Replies
158 Views
SwiftUI in visionOS has a modifier called preferredSurroundingsEffect that takes a SurroundingsEffect. From what I can tell, there is only a single effect available: .systemDark. ImmersiveSpace(id: "MyView") { MyView() .preferredSurroundingsEffect(.systemDark) } I'd like to create another effect to tint the color of passthrough video if possible. Does anyone know how to create custom SurroundingsEffects?
Posted Last updated
.