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)
}
}
}
Post
Replies
Boosts
Views
Activity
Hi, so i'm trying to use Activity.update but XCode throws an error if I don't use the ios 16 syntax, only to throw a warning that it's deprecated if I do. Screenshots below. Should I bug report or is there a known workaround?
I'm trying to create a preview for my live activities when it's stale, so I created a preview provider. I followed some examples, but XCode says I'm missing preview context. Am I doing something wrong?
I tried adding .previewContext(WidgetPreviewContext(family: .systemSmall)) but that doesn't seem to work.
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?
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?
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
...
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
}
}
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
}
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?