The UI on this is completely terrible but hopefully it illustrates how to use a Picker to select the appropriate "scales" value for your calculations.
Cheers,Dan
struct ContentView: View {
@State private var scaleSelector = 0
let scales = [1.000, 1.067, 1.125, 1.200, 1.250, 1.333, 1.414, 1.500, 1.618]
var body: some View {
VStack {
Picker(selection: $scaleSelector, label: Text("Scales")) {
ForEach(0..<scales.count) {
Text("Scale by: \(self.scales[$0])")
}
}.labelsHidden()
Text("Result: \(pxToEms(pixelInt: 2, baseInt: 3, scales: Double(scaleSelector)))")
}
}
func pxToEms(pixelInt: Double, baseInt: Double, scales: Double) -> Double {
let emValue: Double = (pixelInt / baseInt) * scales
return emValue
}
}
Post
Replies
Boosts
Views
Activity
Try this code and see if it's what you're looking for. The gray area of the list background you saw is from the .listStyle(SidebarListStyle()) modifier you have in there. If you remove that the gray area goes away.
I hope this helps.
Dan
struct ContentView: View {
@State private var revealDetails = false
var body: some View {
VStack {
List {
DisclosureGroup("Show some Text", isExpanded: $revealDetails) {
Text("Some Text...")
.padding()
Text("Hello, world!").padding()
Text("Hello, world!").padding()
Text("Hello, world!").padding()
}
}.listStyle(SidebarListStyle())
.padding()
Spacer()
}
}
}
I found the answer to this. It's the tint initializer inside CircularProgressViewStyle. This will display a color but you can also define a Gradient.
.progressViewStyle(CircularProgressViewStyle(tint: Color.yellow))
Along this same thread the Coffee Tracker sample app's complication code is set for a deployment target of watchOS 6.2 and this is a code block for a complication from the sample;
// Return a circular small template.
private func createCircularSmallTemplate(forDate date: Date) -> CLKComplicationTemplate {
// Create the data providers.
let mgCaffeineProvider = CLKSimpleTextProvider(text: data.mgCaffeineString(atDate: date))
let mgUnitProvider = CLKSimpleTextProvider(text: "mg Caffeine", shortText: "mg")
// Create the template using the providers.
let template = CLKComplicationTemplateCircularSmallStackText()
template.line1TextProvider = mgCaffeineProvider
template.line2TextProvider = mgUnitProvider
return template
}
Changing the deployment target to watchOS 7.0 will produce this error:
'init()' was deprecated in watchOS 7.0: Initializing a template without parameters is deprecated in watchOS 7.0. Use an init with parameters instead.
I have set up my own complications to supposedly align with the new init() requirements, however my complication is not showing up in the list of available options. Have I done something incorrect in this example?
Thank you - Dan
func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) {
switch complication.family {
case .circularSmall:
let line1 = CLKSimpleTextProvider(text: "Run Roster")
let line2 = CLKSimpleTextProvider(text: "10 Sep 2021")
let circularSmall = CLKComplicationTemplateCircularSmallStackText(line1TextProvider: line1, line2TextProvider: line2)
handler(circularSmall)
... // more switch cases below.
I found the answer wasn't in my sample template code, but with declaring which complications my app will support with watchOS7. I was not declaring my CLKComplicationDescriptor correctly but fixed it with this.
func getComplicationDescriptors(handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
let descriptors = [
CLKComplicationDescriptor(identifier: "complication", displayName: "Run Roster", supportedFamilies: CLKComplicationFamily.allCases)
// Multiple complication support can be added here with more descriptors/
// Create a new identifier for each new CLKComplicationDescriptor.
]
// Call the handler with the currently supported complication descriptors\
handler(descriptors)
}
I wanted to give this thread a bump because I too am facing the same issue. The proposed answer from rr0924, and the referenced article from Antoine van der Lee, does not work for me either.
To inject my CoreData model into the Widget extension one failing attempt I've tried was to use a similar method in my iOS app and watchOS companion app. For example this code will allow proper access to CoreData from iOS and watchOS;
@main
struct RunRosterApp: App {
@Environment(\.scenePhase) private var scenePhase
@StateObject private var persistentStore = PersistentStore.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistentStore.context)
}
}
The PersistentStore class is a set up as a singleton to load the NSPersistentCloudKitContainer. That code is fairly boiler plate so I won't post it but can upon request.
Using a similar pattern in WidgetKit and SwiftUI I currently have this;
@main
struct WidgetRunPlanner: Widget {
@StateObject private var persistentStore = PersistentStore.shared
private let kind: String = "WidgetRunPlanner"
public var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WidgetRunPlannerEntryView(entry: entry)
.environment(\.managedObjectContext, persistentStore.context)
}
}
Unfortunately this is not right and the Widget will crash at the first attempt of a CoreData fetch request with the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'RunEvents'' If you have any experience with this any help is greatly appreciated. The Target Membership checkbox's have been appropriately checked.
Thank you,
Dan
Perhaps you've solved this already, but if you click the refresh icon below the app group identifier list that should clear up the red lettering. This forum won't let me post the link but if you search YouTube for the video from Kilo Loco titled "Creating Your First SwiftUI Widget | iOS 14", he discusses the process of creating App Groups. It was helpful for me.
Dan
I believe the problem is a bug in the .toolbar where items will not show up. If you replace Apple's default code and use .navigationBarItems (instead of .toolbar) you'll be able to see the buttons so you can add items to the CoreData list. Replace the default View body code with this and it should work for you.
var body: some View {
NavigationView {
List {
ForEach(items) { item in
Text("Item at \(item.timestamp!, formatter: itemFormatter)")
}
.onDelete(perform: deleteItems)
}
.navigationBarItems(leading: EditButton(),
trailing: Button(action: addItem, label: { Label("Add Item", systemImage: "plus") })
)
}
}
It's an issue with this block of code:
.toolbar {
#if os(iOS)
EditButton()
#endif
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
if you replace the View with this you should see a "+ Add Item" button in the menu which will add items to CoreData.
var body: some View {
NavigationView {
List {
ForEach(items) { item in
Text("Item at \(item.timestamp!, formatter: itemFormatter)")
}
.onDelete(perform: deleteItems)
}
.navigationBarItems(trailing: Button(action: addItem) {
Label("Add Item", systemImage: "plus")
})
}
}
I field Feedback on issues with .toolBar back in July and it hasn't been resolved yet. FB8101065
If your deployment target is set to watchOS7 for the minimum version your app may not be looking for your ExtensionDelegate any longer. You can use the property wrapper @WKExtensionDelegateAdaptor to observe your ExtensionDelegate. Make sure your ExtensionDelegate conforms to ObservableObject. Something to this effect should work.
@main
struct RunPlanner: App {
@Environment(\.scenePhase) var scenePhase
@WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print("\(#function) REPORTS - App change of scenePhase to ACTIVE")
case .inactive:
print("\(#function) REPORTS - App change of scenePhase Inactive")
case .background:
startBackgroundRefresh()
default:
print("\(#function) REPORTS - App change of scenePhase Default")
}
}
}
Make sure your ExtensionDelegate conforms to ObservableObject. For example;
class ExtensionDelegate: NSObject, ObservableObject, WKExtensionDelegate {		
var meetingStatistics:	MeetingStatistics = MeetingStatistics()
}
It's mentioned rather quietly in the second init() that the class needs to conform to ObservableObject.
https://developer.apple.com/documentation/swiftui/wkextensiondelegateadaptor
I had this problem as well and I believe what I did wrong was when I created the iCloud container ID I manually typed in the "iCloud" at the start of the bundle ID. For example I created the iCloud container ID as "iCloud.com.myBundleName.myCompany".
Xcode automatically adds the "iCloud" to the beginning of the name you type, so I believe what it was seeing was "iCloud.iCloud.com.myBundleName.myCompany" and thus giving the error.
Try just typing "com.whateverBundleName.whateverCompany" and Xcode will add the iCloud at the beginning automatically. That solved the error for me.