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

SwiftUI Map Annotation Coordinate Animation
Hi, I have a SwiftUI Map with a set of three annotations. These annotations move around, and I would like to animate their movement from one coordinate to another, but I'm not finding a way to do that. I've tried using withAnimation { } when setting my array of Identifiable models that back the Annotations, and I've tried adding the .animation(.default, annotationModels) modifier to my Map object (where annotationModels is the array that backs my Annotations). The animation modifier doesn't work on Annotation structs, and it doesn't work if I add the animation modifier within the Annotation's view either. Does anyone have any suggestions on how I might be able to animate the coordinates of annotations using a SwiftUI Map? Does the problem have to do with the fact that I have an array of these annotations?
0
0
147
1w
Infinite loop using NavigationStack
Hello. I've seen some other posts about NavigationStack, but my variation seems a little different. FYI, I have not migrated from ObservableObject to Observable yet. However, having a path in either seems to be a factor in this issue. My code has no issues when built with Xcode 15. When built with Xcode 16 I keep hitting scenarios where the .onAppear for my first tab gets called over and over again endlessly. If I go to my second tab, which uses a NavStack with a path and then navigate anywhere my .onAppear for my FIRST tab gets call endlessly. I’ll sometimes see a “double push” to the stack. (Someone posted a video of this happening on Mastodon, which apparently I’m not allowed to link to here.) The second tab is accessing the path property via an @EnvironmentObject. I can stop this endless loop by removing @Published from the property in my ObservableObject that holds my path. But then if I go to my third tab, which does NOT use a path, the .onAppear for my FIRST tab again gets called endlessly. So far on Mastodon I’ve seen three people encountering problems possibly related to storing a path in something being observed. Feedback requires a sample project, which I am having trouble creating to show the problem.
4
1
196
1w
Swift Chart Zoom/Magnification/Pinch Gesture
Is there any approach or sample code available to use these APIs: .chartScrollableAxes(.horizontal) .chartScrollPosition(x: ...) .chartScrollPosition(initialX: ...) .chartScrollTargetBehavior(...) .chartXVisibleDomain(length: ...) Plus a gesture recognised or Pinch or Magnification to create a Swift Chart with an X axis that can be zoomed in or out with a pinch gesture? And when zoomed in at any level above 0, the chart can then be scrolled left to right along the X axis. I've had success using .chartScrollableAxes with .chartXSelection in parallel, so would also like to keep the ability to select X values too.
0
0
164
1w
[Live Activity / Dynamic Island] Countdown Timer issues (ending activity, styling)
Hello! I'm building a Countdown Timer for the Dynamic Island using a Live Activity. I have two issues for which I can't find any solution: We want to display the time in the "X minutes" format, like in this example. I went through the forum but all the answers were wrong, because they were using a Text(:format) which never updates in the live activity, or a Text(:timerInterval) which we can't format. I want the Live Activity to end once the timer gets to zero. I found this staleDate parameter that I thought would helped, but is actually only adding loaders on my design once the date is reached. I tried to implement a solution like the answer of this post, but the if (context.isStale) {...} part is never being rendered. It also looks like the stale sate gets activated only when the app is focus again. I tried several fixes, went through a lot of forum and posts, but I can't find any solution. Thanks!
0
0
155
1w
Text Don't Show in swipeActions buttons !
Hi, I have the below code and don't know why the text doesn't show fro swipe buttons just the icons show ? Kind Regards import SwiftUI struct NewView: View { var body: some View { NavigationStack { List { ForEach(1...7, id: \.self) { number in VStack { Text("Item \(number)") .padding() } .swipeActions(edge: .trailing) { Button(role: .destructive) { withAnimation { deletePatient2() } } label: { Label("Delete", systemImage: "trash.fill") } Button { deletePatient2() // toDoToEdit = item } label: { Label("Edit", systemImage: "pencil") } .tint(.orange) } } } } .listStyle(.plain) } func deletePatient2() { } } #Preview { NewView() }
3
0
160
1w
[VisionOS] .onDelete gesture not triggered for mouse
I found a regression in Apple Vision OS 2.0 beta 3 (22N5277g). Previously, it was possible to trigger the .onDelete swipe gesture on a List/ForEach with a virtual mouse (i.e. remote desktop), however this is no longer possible (a finger pinch still works). Sample code to reproduce the issue: // // ContentView.swift // TextInputTest // import SwiftUI struct ListElement: Identifiable { let id = UUID() let content: String } struct ContentView: View { @State var list = [ ListElement(content: "a"), ListElement(content: "b"), ListElement(content: "c") ] var body: some View { List { ForEach(list) { element in Text(element.content) } .onDelete { _ in // No-op. } } } }
0
0
112
1w
[VisionOS] TextEditor does not respect .autocorrectionDisabled
Hello everyone, I wanted to double check with the UI Framework team to see if there's a mistake in my code or if there's some sort of regression. My goal is to have a user input text without any automatic modification of said text, namely remove auto-capitalization and auto-correct. // // ContentView.swift // TextInputTest // import SwiftUI struct ContentView: View { @State var text: String = "Enter some text here!" var body: some View { VStack { TextEditor(text: $text) .autocorrectionDisabled(true) .textInputAutocapitalization(.never) .font(Font.custom("SF Mono", size: 30)) .monospaced() .padding(20) } .padding() } } However, when typing the following: "This is a sentence" followed by a few spaces, a dot will automatically be inserted, making the string become: "This is a sentence.". Reproduced on: VisionOS 2.0 beta 3 (22N5277g)
1
0
136
1w
Drag Gestures
Dear all, I am experiencing some problems with the Drag Gesture in VisionOS. Typically, this gesture involves the user pinching an entity or, more commonly, a window, and moving/dragging it around. However, this is not always the case for entities (3D models) placed in the environment. It appears that the user can both pinch and drag and/or move the entity with their bare hands. In the latter case, the onChange cycle doesn't always end if the user keeps their hands near the object, causing it to keep moving even if that is not what the user intends. This also occurs when the user is no longer hovering over that entity. Larger entities, more so than those in the demo "TransformingRealityKitEntitiesUsingGestures," close to the user seem to become attached to their hands, causing the gesture to continue indefinitely. Entities often move to unintended positions. I believe that these two different behaviors within the same gesture container are intrinsically different: one involves pinching and dragging, while the other involves enabling hands physics, and it should be easy to distinguish between the two. How can we correctly address this situation? Thank you for your assistance
3
0
174
1w
Can't figure out why Toolbar is not conforming to view
ToolbarItem in group is not conforming to view for some reason, here's my code: var body: some View { NavigationStack { Form { TextField("Company Name", text: $companyName) TextField("Role", text: $role) TextField("Location", text: $location) TextField("Yearly Salary", value: $yearlySalary, format: .currency(code: "USD")) .keyboardType(.decimalPad) } .navigationTitle("Add Application") .navigationBarTitleDisplayMode(.large) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("back") { dismiss() } } ToolbarItem(placement: .navigationBarTrailing) { Button("Save") { let appdata = ApplicationData( companyName: companyName, role: role, location: location, yearlySalary: yearlySalary, dateApplied: dateApplied, notes: notes) // Save the application data dismiss() } } } } } The error reads: Static method 'buildExpression' requires that 'ToolbarItem<(), Button>' conform to 'View' I'm trying to change it up but I can't get past this error for some reason
2
0
157
1w
List Closure not displaying retrieved data in Simulator UI
I have backend API caller file that retrieves and displays unwrapped JSON data via URLRequest(). All the data is printed to my console when I build the project but it's not being displayed in the actual UI of my iOS simulator. I have a class in my ContentView that updates the UI and filters the extracted fields shown here below: class NotionCall: ObservableObject { @Published var extractedContent: [BlockBody.Block] = [] func makeAPIRequest() { makeRequest { results in let extractedData = results.map { block -> BlockBody.Block in var extractedBlock = block extractedBlock.ExtractedFields = block.paragraph?.textFields.compactMap { textField in textField.PlainText ?? textField.RichText ?? textField.content //iterate over PlainText, RichText, and Content fields and return the non nill values } ?? [] //validate objects even if they are nil return extractedBlock } DispatchQueue.main.async { self.extractedContent = extractedData } } } } @StateObject var NotionCaller = NotionCall() //manage lifecycle of instance And then below here is my SwiftUI structure that contains List(NotionCaller.extractedContent) { block in ForEach(block.ExtractedFields, id: \.self) { field in Text(field) meant to display the extracted data to the UI: var body: some View { NavigationStack { ZStack { List(NotionCaller.extractedContent) { block in ForEach(block.ExtractedFields, id: \.self) { field in Text(field) } } ZStack { Color(hex: "#f9f9f9") .ignoresSafeArea() VStack { TextField(" Search keywords", text: $searchKeywords) //change font later .frame(height: 48) .overlay(RoundedRectangle(cornerRadius: 30).strokeBorder(style: StrokeStyle())) .foregroundColor(.white) .background(.white) .cornerRadius(30) .padding() .scaledToFit() .frame(maxHeight: .infinity, alignment: .top) } VStack { Spacer() Divider() .padding() HStack { Button(action: { //add functionality later }) { Image("menuButton") .frame(alignment: .bottom) .padding(.horizontal, 42) Spacer() } HStack { Button(action: { //add functionality later }) { Image("notificationButton") .frame(alignment: .leading) .padding(.leading, 30) Spacer() } } HStack { Button(action: { }) { Image("notionImportButton") .frame( alignment: .trailing) .padding(.horizontal) .padding(.horizontal) } } } .onAppear { NotionCaller.makeAPIRequest() } } } } } } }
4
0
226
1w
Section Fully Clickable in SwiftUI – NavigationLink Issue
Hi everyone, I’m having an issue with SwiftUI where my entire Section becomes clickable, instead of just the “Edit profile” button. Here’s my code: VStack(alignment: .center) { KFImage(authManager.user?.photoURL) .resizable() .scaledToFill() .frame(width: 80, height: 80) .clipShape(Circle()) Text(authManager.user?.displayName ?? "") .font(.system(.title, design: .rounded)) Text(authManager.user?.email ?? "") .font(.subheadline) .foregroundColor(.gray) NavigationLink { EditProfileView() } label: { Text("Edit profile") .frame(minWidth: 0, maxWidth: .infinity) .font(.system(size: 18)) .padding(10) .foregroundColor(.white) .background(Color.blue) .cornerRadius(25) } .padding(.top, 5) } .frame(maxWidth: .infinity, alignment: .center) } I want only the button to be clickable. How can I fix this? Thanks! Link to issue: https://imgur.com/a/iO9aNSM
1
0
144
1w
SwiftUI view is not updated properly
Task: A child view should show depending on a boolean flag the corresponding view. The flag is calculated from a model which is given by parent view. Problem: The flag is false in init, which is correct. However in body it's true, which is incorrect. Why value in body isn't consistent to init? Is there a race condition? The child view's is rendered thrice, that's another issue, but flag is in init and body as described before. Parent view looks like this: struct ParentView: View { private var groupedItems: [GroupedItems] = [] init(items: [Item]) { Dictionary(grouping: items) { $0.category.name } .forEach { let groupedItems = GroupedItems(categoryName: $0.key, items: $0.value) self.groupedItems.append(groupedItems) } } var body: some View { ChildView(groupedItems) } } Child view looks like this: struct ChildView: View { @State private var showItems: Bool init(_ groupedItems: GroupedItems) { self._showItems = State(initialValue: !groupedItems.completed) } var body: some View { if showItems { AView() } else { BView() } } } Model looks like this: @Model final class Item: Identifiable { @Attribute(.unique) public var id: String public var name: String public var completed = false } struct GroupedItems { var categoryName: String var items: [Item] var completed: Bool { items.filter { !$0.completed }.isEmpty } }
3
0
215
1w
new developer, need help displaying on screen
brand new newbie developer to xcode. so im doing an api call and getting back data from a mysql database. in the xcode preview window im getting data, but i cant figure out how to tie it to the screen when going into the simulator. i have screen 1 that i want to click a button to go to screen 2 that displays the data. screen one (home screen) comes up okay. cant quite figure out what im doing wrong here. im thinking its either a class issue or something to do with view or something. not sure. ive tried looking at so many different videos and i cant seem to find my answer. Any help would be appreciated. thank you View Controller: import UIKit //import SwiftUI let URL_TOURNAMENT_FETCH = "https://www.thesoftball.com/t2g_mobile_app/mobile_api.php" class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func onEmailButtonPressed(_ sender: Any) { UIApplication.shared.open(URL(string: "mailto:[email]")! as URL, options: [:],completionHandler: nil) } /* @IBAction func FetchTournButton(_ sender: Any) { UIApplication.shared.open(URL(string: "https://www.thesoftball.com/t2g_mobile_app/mobile_api.php")! as URL, options: [:],completionHandler: nil) } */ @IBAction func ViewTournamentButton(_ sender: Any) { // the following is a popup let alertController = UIAlertController(title: "Welcome to My First App", message: "Hello World", preferredStyle: UIAlertController.Style.alert) alertController.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil)) present(alertController, animated: true, completion: nil) } @IBAction func account_button_pressed(_ sender: Any) { UIApplication.shared.open(URL(string: "https://www.thesoftball.com")! as URL, options: [:],completionHandler: nil) } /* struct viewDidLoadModifier: viewDidLoadModifier { @State private var didLoad = false private let action: (() -> void)? init(perform action) { } } */ } ContentView (preview works in this) import SwiftUI struct ContentView: View { @StateObject var viewModel = ViewModel() var body: some View { NavigationView{ List{ ForEach(viewModel.courses,id: \.self) { tournament in HStack { Image("") .frame(width: 5, height: 120) .background(Color.orange) VStack { Text(tournament.name).bold() Text(tournament.dates) Text(tournament.datee) Text(tournament.location) // Text(course.location) // Text(course.message) // .bold() } } .padding(0) } } .navigationTitle("Tournaments") // .onAppear { viewModel.fetch()} .onAppear(perform: viewModel.fetch) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
0
0
185
2w
NSHostingView Not Working With Swift 6.0
I recently compiled my macOS App with Swift 6 in Xcode 16 (was using Swift 5 previously) and noticed that AppKit Integration doesn't appear to be working as before. All my instances of NSHostingView which allow me to add a SwiftUI View to an AppKit NSWindow view controller no longer respond to mouse input anymore. All my NSHostingView instances display but refuse to accept any user interaction. Has anyone else noticed this and is there a workaround to get NSHostingView to once again be able to accept user/mouse events with Swift 6?
6
0
248
1d
Problem with NavigationLink
I am making application where I use navigation link to navigate from bottom menu to other views, and there is a problem when I change view a few times because views start stacking and when I set navigationBarBackButtonHidden(false) I can see on left side a lot of back button. This generate big problem because after changing views I got warning Abnormal number of gesture recognizer dependencies: 100. System performance may be affected. Please investigate reducing gesture recognizers and/or their dependencies. And after some more changes everything from screen is pushed down back button. Is there any solution to close previous view from we came? There is code: // // BottomMenu.swift // SpaceManager // // Created by Kuba Kromomołowski on 04/05/2024. // import SwiftUI import Firebase import FirebaseAuth struct BottomMenu: View { @StateObject var logManager = MainViewModel() @StateObject var mvm = MenuViewModel() @State var condition1: Bool = true @State var condition2: Bool = false @State var condition3: Bool = false // @StateObject private var cameraViewModel = CameraViewModel() var body: some View { HStack{ Group{ //.navigationBarBackButtonHidden(true) Spacer() BtnMenu(btnText: "Dodaj", btnIcon: "plus.app.fill", destinationView:AnyView(LoggedMainView()), isActive: condition1 ) Spacer() BtnMenu(btnText: "Szukaj", btnIcon: "magnifyingglass", destinationView:AnyView(SearchView()), isActive: condition2 ) Spacer() BtnMenu(btnText: "Profil", btnIcon: "person.crop.circle.fill", destinationView:AnyView(ProfileView()), isActive: condition3 ) Spacer() }.padding(.bottom, 30) .font(.system(size: 20)) } } } #Preview { BottomMenu() } // // BtnMenu.swift // SpaceManager // // Created by Kuba Kromomołowski on 04/05/2024. // import SwiftUI struct BtnMenu: View { var btnText: String var btnIcon: String var destinationView: AnyView @State var isActive: Bool = true var body: some View { NavigationLink{ destinationView } label: { ZStack { Text("\(Image(systemName: btnIcon)) \(btnText)") } }.disabled(isActive) } }
1
0
138
2w
Use of SceneDelegate not working
I am trying to configure scenes to capture a redirect URL after a successful login attempt. I am using OAuth code flow. This is the code I have so far: ios_app.swift import SwiftUI @main struct ios_appApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate let persistenceController = PersistenceController.shared @StateObject private var authState = AuthState() var body: some Scene { WindowGroup { ContentView() .environment(\.managedObjectContext, persistenceController.container.viewContext) .environmentObject(authState) } } } AppDelegate.swift import UIKit import AWSMobileClient import GoogleSignIn class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { print("AppDelegate: didFinishLaunchingWithOptions") AWSMobileClient.default().initialize { (userState, error) in if let userState = userState { print("UserState: \(userState)") } else if let error = error { print("Error initializing AWSMobileClient: \(error.localizedDescription)") } } GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in if let error = error { print("Error restoring previous Google Sign-In: \(error.localizedDescription)") } } return true } } SceneDelegate.swift import UIKit import SwiftUI import GoogleSignIn class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { print("SceneDelegate: scene willConnectTo") guard let windowScene = (scene as? UIWindowScene) else { print("SceneDelegate: Invalid windowScene") return } let window = UIWindow(windowScene: windowScene) let contentView = ContentView().environmentObject(AuthState()) window.rootViewController = UIHostingController(rootView: contentView) self.window = window window.makeKeyAndVisible() print("SceneDelegate: window initialized and visible") } func sceneDidDisconnect(_ scene: UIScene) { print("SceneDelegate: sceneDidDisconnect") } func sceneDidBecomeActive(_ scene: UIScene) { print("SceneDelegate: sceneDidBecomeActive") } func sceneWillResignActive(_ scene: UIScene) { print("SceneDelegate: sceneWillResignActive") } func sceneWillEnterForeground(_ scene: UIScene) { print("SceneDelegate: sceneWillEnterForeground") } func sceneDidEnterBackground(_ scene: UIScene) { print("SceneDelegate: sceneDidEnterBackground") } func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { guard let url = URLContexts.first?.url else { print("SceneDelegate: No URL found in URLContexts") return } print("SceneDelegate: openURLContexts with URL: \(url)") if GIDSignIn.sharedInstance.handle(url) { print("SceneDelegate: Google Sign-In handled URL") return } if url.scheme == "myurlscheme" || (url.scheme == "https" && url.host == "mydomain.com" && url.path == "/mobile-auth-callback") { print("SceneDelegate: Handling auth response for URL: \(url)") AuthService.shared.handleOAuthCallback(url: url) } else { print("SceneDelegate: URL scheme not handled: \(url.scheme ?? "No scheme")") } } func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { print("SceneDelegate: continue userActivity") if userActivity.activityType == NSUserActivityTypeBrowsingWeb { if let url = userActivity.webpageURL { handleUniversalLink(url: url) } } } private func handleUniversalLink(url: URL) { print("SceneDelegate: Handling universal link: \(url)") if url.path.contains("/mobile-auth-callback") { let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems let code = queryItems?.first(where: { $0.name == "code" })?.value if let code = code { print("SceneDelegate: Received code: \(code)") AuthService.shared.exchangeCodeForToken(code: code) } else { print("SceneDelegate: No code found, handling email/password callback") AuthService.shared.handleEmailPasswordCallback(url: url) } } } } Also introduced this configuration in Info.plist: <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>UIApplicationSceneManifest</key> <dict> <key>UIApplicationSupportsMultipleScenes</key> <true/> <key>UISceneConfigurations</key> <dict> <key>UIWindowSceneSessionRoleApplication</key> <array> <dict> <key>UISceneConfigurationName</key> <string>Default Configuration</string> <key>UISceneDelegateClassName</key> <string>ios-app.SceneDelegate</string> </dict> </array> </dict> </dict> ...Other parameters </dict> </plist> I am using the simulator to launch my app and can see AppDelegate related logs but I am not seeing any SceneDelegate logs (I suppose because it is not being initialized nor called). I have tried restarting the computer/Xcode, clean and rebuild the application but none of the things I tested work. Is there any part of my code wrong? Any other idea here?
0
0
107
2w
Issues Supporting All Accessibility Features with a Custom Font
I am in the process of adding my company's brand font to our SwiftUI app. I am able to implement the font using the provided public APIs so that text styles / dynamic type and the font weight modifier in SwiftUI work correctly. However we are unable to implement custom font in such a way that text styles / dynamic type, the font weight modifier, and the bold text accessibility setting all work at the same time. Am I missing an implementation detail so that all these features work correctly? Font Setup The font files were modified to better support SwiftUI: The font style name metadata was modified to match the name the .fontWeight(...) modifier expects. This was done with Typelight. The font weight value (100/200/300) was modified so that the underlying weight value matches the value the .fontWeight(...) modifier expects. See "Using custom fonts with SwiftUI" by Matthew Flint. The font files were imported via the Info.plist. Examples Font Weight Comparison San Fransisco: Text("#100") .font(.largeTitle) .fontWeight(.ultraLight) Overpass by Name: Text("#100") .font(.custom("Overpass-UltraLight", size: 34, relativeTo: .largeTitle)) Overpass by Weight: Text("#100") .fontWeight(.ultraLight) .font(.custom("Overpass", size: 34, relativeTo: .largeTitle)) Legibility Weight Test When using the .fontWeight(...) modifier, the custom font does not change weights when the bold text accessibility setting is enabled. Dynamic type size works as expected. Normal legibility weight: Bold legibility weight: Dynamic Type Size: Use UIFont Using UIFont to load the custom font files and initializing a Font with the UIFont breaks dynamic type: Bold type also does not work: Custom Modifier Creating a custom modifier allows us to support dynamic type and manually handle bold text. However it creates a conflicting API to SwiftUI's .fontWeight(...) modifier. struct FontModifier: ViewModifier { enum UseCase { case paragraph case headline } enum Weight { case light case regular case heavy } @Environment(\.legibilityWeight) var legibilityWeight var useCase: UseCase var weight: Weight init(_ useCase: UseCase, _ weight: Weight) { self.useCase = useCase self.weight = weight } var resolvedHeadlineWeight: String { let resolvedLegibilityWeight = legibilityWeight ?? .regular switch weight { case .light: switch resolvedLegibilityWeight { case .regular: return "Light" case .bold: return "Semibold" @unknown default: return "Light" } case .regular: switch resolvedLegibilityWeight { case .regular: return "Regular" case .bold: return "Bold" @unknown default: return "Regular" } case .heavy: switch resolvedLegibilityWeight { case .regular: return "Heavy" case .bold: return "Black" @unknown default: return "Heavy" } } } var resolvedParagraphWeight: Font.Weight { switch weight { case .light: return .light case .regular: return .regular case .heavy: return .heavy } } var resolvedFont: Font { switch useCase { case .paragraph: return .system(.largeTitle).weight(resolvedParagraphWeight) case .headline: return .custom("Overpass-\(resolvedHeadlineWeight)", size: 34, relativeTo: .largeTitle) } } func body(content: Content) -> some View { content .font(resolvedFont) } } GridRow { Text("Aa") .modifier(FontModifier(.paragraph, .regular)) Text("Aa") .modifier(FontModifier(.paragraph, .heavy)) Text("Aa") .modifier(FontModifier(.headline, .regular)) Text("Aa") .modifier(FontModifier(.headline, .heavy)) } Font Environment Value The font environment value does not contain font weight information when the fontWeight(...) modifier is used.: struct DumpFontTest: View { @Environment(\.font) var font var body: some View { Text("San Fransisco") .onAppear { print("------------") dump(font) } } }
2
1
208
6d
Really High Energy Use
I'm developing an app where users can select items to add to a screen, similar to creating a Canva presentation or choosing blocks in Minecraft. However, I'm encountering an issue with energy usage. When users click the arrows to browse different items, the energy use spikes significantly. Although it returns to normal after a while, continuous clicking causes the energy use to skyrocket. The images I'm using are 500x500 pixels. Ideally, I would like to avoid caching all the images, as the app might have up to 500 items and caching them all would consume too much memory. I have tried numerous way to avoid this but I just can’t seem to make it work. Would anyone know how to avoid such problem? I have included a picture of the energy use when just opened, and one after like 10 seconds of continuously clicking on an arrow to see more items. Also a picture of how the app looks. struct ContentView: View { struct babyBackground { var littleImage = "" } @State var firstSet: [babyBackground] = [ babyBackground(littleImage: "circle"), babyBackground(littleImage: "square"), babyBackground(littleImage: "triangle"), babyBackground(littleImage: "anotherShape"), babyBackground(littleImage: "circle"), babyBackground(littleImage: "square"), babyBackground(littleImage: "triangle"), babyBackground(littleImage: "anotherShape") ] @State var secondSet: [babyBackground] = [ babyBackground(littleImage: "circle"), babyBackground(littleImage: "square"), babyBackground(littleImage: "triangle"), babyBackground(littleImage: "anotherShape"), babyBackground(littleImage: "circle"), babyBackground(littleImage: "square"), babyBackground(littleImage: "triangle"), babyBackground(littleImage: "anotherShape"), babyBackground(littleImage: "circle") ] @State var thirdSet: [babyBackground] = [ babyBackground(littleImage: "circle"), babyBackground(littleImage: "square"), babyBackground(littleImage: "triangle"), ] let columns: [GridItem] = Array(repeating: .init(.flexible()), count: 4) func createBackgroundGridView(for backgrounds: [babyBackground], columns: [GridItem] ) -> some View { LazyVGrid(columns: columns, spacing: 10) { ForEach(0..<backgrounds.count, id: \.self) { index in Button(action: { }, label: { if let path = Bundle.main.path(forResource: backgrounds[index].littleImage, ofType: "png"), let uiImage = UIImage(contentsOfFile: path) { Image(uiImage: uiImage) .resizable() .frame(width: 126, height: 96) } }) } } .padding() } @State var indexOn = 0 var body: some View { HStack{ Button(action: { indexOn = (indexOn == 0) ? 2 : indexOn - 1 }) { Label("", systemImage: "arrowtriangle.left.fill") .font(.system(size: 50)) } Spacer() ScrollView { switch indexOn { case 0: createBackgroundGridView(for: firstSet, columns: columns) case 1: createBackgroundGridView(for: secondSet, columns: columns) case 2: createBackgroundGridView(for: thirdSet, columns: columns) case 3: createBackgroundGridView(for: thirdSet, columns: columns) default: createBackgroundGridView(for: firstSet, columns: columns) } } .frame(maxWidth: .infinity, maxHeight: .infinity) Spacer() Button(action: { indexOn = (indexOn == 2) ? 0 : indexOn + 1 }) { Label("", systemImage: "arrowtriangle.right.fill") .font(.system(size: 50)) } } } } Energy Use when app starts: Energy use after clicking for about 10 seconds: App UI:
1
1
143
5d