Post

Replies

Boosts

Views

Activity

SwiftUI charts, how do I align these X axis labels correctly?
Hi there, so I have this chart that's taking in a Date for it's x values and a time interval for their y values. For some reason, the labels aren't centering on each bar, the only fix I see is to add an offset to each label but that seems hacky. My code: Chart { ForEach(weekBreakdownArr, id: \.startDate) { bd in BarMark( x: .value("Date", bd.startDate), y: .value("Duration", bd.durationWorkDone), width: .fixed(15) ) .foregroundStyle(Color.redYarn) .cornerRadius(2) } //... } // shownXValues are just the start dates in an array .chartXAxis { AxisMarks(position: .automatic, values: shownXValues) { val in AxisValueLabel { Text("Th") .useAppFont(size: 12, relativeTo: .body, weight: .regular) } } }
1
0
125
1w
Problems with Widget buttons not getting pressed
So I have a button on a widget styled as seen below. I want this button to take up the entirety of the width, problem is, when it does so either using a frame(maxWidth: .infinity) or if I increase the horizontal padding, the button still only gets clicked if the user taps near the buttons center. Otherwise, it will open the app. Relevant code: Button(intent: Intent_StartRest() ){ Text("stop") } .buttonStyle(PlainButtonStyle()) .tint(.clear) .padding(.vertical, 6) .padding(.horizontal, 100) .background(RoundedRectangle(cornerRadius: 30).fill(.button)) .foregroundStyle(.buttonText) // Just sets text color .useAppFont(size: 18, relativeTo: .caption, weight: .bold) // Just sets font Any pointers?
0
0
174
Nov ’24
Not understanding TimelineReloadPolicy in WidgetKit
Relevant docs: https://developer.apple.com/documentation/widgetkit/timelinereloadpolicy I don't understand how .atEnd and .after works and how they differ. So here's what I want: I want to display my widget then update it in 5 seconds. Now I know these examples show that I can use the .after policy like so: let timeline = Timeline( entries:[entry], policy: .after(nextUpdateDate) // 5 seconds after now ) But from reading the docs, .atEnd means: "A policy that specifies that WidgetKit requests a new timeline after the last date in a timeline passes." So why can't we do: let timeline = Timeline( entries:[entry1, entry2], // entry 2 has date 5 seconds after policy: .atEnd ) I tried this and it does not seem to work. When I say I tried, I just had an onAppear on my widget view to print out the entry dates, and the entry 5 seconds later never prints. So what does .atEnd actually do? What happens if we put .atEnd with 1 entry?
1
0
209
Nov ’24
Problems with navigation stack inside a tab view
So basically, if I put a .navigationModifier inside of a NavigationStack that's inside of a TabView, AND I supply a path argument to NavigationStack. I get this error: Do not put a navigation destination modifier inside a "lazy” container, like `List` or `LazyVStack`. These containers create child views only when needed to render on screen. Add the navigation destination modifier outside these containers so that the navigation stack can always see the destination. There's a misplaced `navigationDestination(for:destination:)` modifier for type `NavPath`. It will be ignored in a future release. Does TabView or NavigationStack suddenly become lazy when I put the path parameter in? It also causes weird unexplained behavior if I start removing tabs using state, but I do think I'm not supposed to do that. Code for reference: var body: some View { @Bindable var nm = navManager TabView{ NavigationStack(path: $nm.pathStack){ HomeView() // A custom view .navigationDestination(for: NavPath.self) { np in // NavPath is a custom struct that's hashable switch np.pathId { case "home": NavigationLazyView(HomeView()) // Ignore the NavigationLazyView, does not affect ...
3
1
623
Aug ’24
Testing StoreKit refunds always returns an error, but items get refunded anyway
Hi all, I'm using StoreKit views for my in app store. While testing locally with a local storekit config, I can display the refund sheet for the correct product and tap refund, but my onRefundDismiss always handles the .failure case. The error messages I get have been non descriptive, i.e "Unable to Request Refund". Weirdly enough, I can confirm through transaction manager that the refund does go through, it's just my onDismiss function is getting a failure case for some reason. Any help is appreciated. The code below // Somewhere in body MyView() .refundRequestSheet(for: storeModel.productId ?? 0, isPresented: $isShowRefund, onDismiss: onRefundDismiss) // onRefundDismiss private func onRefundDismiss(result: Result<StoreKit.Transaction.RefundRequestStatus, StoreKit.Transaction.RefundRequestError>){ switch result { case .success(let refundStatus): switch refundStatus { case .success: storeModel.handleBlockRefund() // Some function I call case .userCancelled: break @unknown default: break } case .failure(let errorVal): alertTitle = "Refund failed" alertMsg = errorVal.localizedDescription } }
0
0
344
Aug ’24
Using core data in ShieldConfigurationExtension
Hi there, In short, I'm trying to use CoreData in my ShieldConfigurationDataSource extension. Trying to fetch from core data at all seems to cause the shield to render it's default look. I already added the extension to an app group + configured my persistence store to use the app group. Below is my code, any help is appreciated: // Shield extension override func configuration(shielding application: Application) -> ShieldConfiguration { do { let appSelectionId = "***" let blockedItemReq = ... blockedItemReq.predicate = ... let moc = PersistenceController.shared.container.viewContext // Commenting this and the bottom out makes it work, but I need the data! let blockedItemRes = try moc.fetch(blockedItemReq) let shieldTitle = ShieldConfiguration.Label(text: "Hello there", color: .red) return ShieldConfiguration(backgroundColor: .black, title: shieldTitle) } catch { let shieldTitle = ShieldConfiguration.Label(text: "ERROR \(error.localizedDescription)", color: .white) return ShieldConfiguration(backgroundColor: .black, title: shieldTitle) } } // Persistence Controller init(inMemory: Bool = false) { container = NSPersistentContainer(name: "AppBlockerOne") if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") } else { let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.appblockerone")! let storeURL = containerURL.appendingPathComponent("AppBlockerOne.sqlite") let description = NSPersistentStoreDescription(url: storeURL) container.persistentStoreDescriptions = [description] } container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } }) container.viewContext.automaticallyMergesChangesFromParent = true }
2
0
399
Aug ’24
[SwiftUI] When to use closures vs equals for variable assignment?
Hi, I'm new to swift but have experience with coding in general. Following the app dev training tutorial, came across this line of code: var wrapper: ErrorWrapper { ErrorWrapper(error: someVal) } My question is, why not just do this... var wrapper: ErrorWrapper = ErrorWrapper(error: someVal) Is it a conventions thing or is there some purpose, code seems to work either way. My understanding of closures is that they are just lambda functions, so in the first codeblock, all it's doing is calling a function that returns the instantiated ErrorWrapper object. Why not just assign the variable to it?
1
0
419
Jul ’24