How to add multiple accessoryCircular widget? - swift

I created 3 circular widget for the lockscreen (IOS 16). They work great, but only 1 shows up in the simulator and my real iPhone. How can I make them all show up ?
Here is the switch I use:
struct PlaneCalcWidgetView: View {
#Environment(\.widgetFamily) var size
var entry: WidgetProvider.Entry
var body: some View {
if #available(iOSApplicationExtension 16.0, *) {
switch size {
case .systemSmall:
SmallWidgetView(entry: entry)
case .systemMedium:
MediumWidgetView(entry: entry)
case .systemLarge:
LargeWidgetView(entry: entry)
case .accessoryCircular:
gaugeCircularWidget(entry: entry) <= First ONE
case .accessoryCircular:
gaugeMassCircularWidget(entry: entry) <= second ONE
case .accessoryCircular:
gaugePaxCircularWidget(entry: entry) <= third ONE
case .accessoryRectangular:
gaugeLinearWeatherWidget(entry: entry)
#unknown default:
Text("Unknown")
}
} else {
switch size {
case .systemSmall:
SmallWidgetView(entry: entry)
case .systemMedium:
MediumWidgetView(entry: entry)
case .systemLarge:
LargeWidgetView(entry: entry)
#unknown default:
Text("Unknown")
}
}
}
}

You cannot have multiple of same widget sizes in the same widget struct. In your case your widget struct is 'PlaneCalcWidgetView'.
Solution is to create another widget struct. Then Create a widget bundle to include 2 (or more) widget structs. Please note that you have to remove the #main from your original Widget struct. Instead, put #main in Widget Bundle.
#main
struct WidgetBundle_widget: WidgetBundle {
#WidgetBundleBuilder
var body: some Widget {
PlaneCalcWidgetView_Widget() //This is your Widget struct.
PlaneCalcWidgetView_Second_Widget()
PlaneCalcWidgetView_Third_Widget()
}
}

Related

Enumerate over unique enum cases ignoring associated value

I want to achieve fast enumeration so that I can express this enum as a contiguous monotonic sequence of unique integer values, one for each case (starting at zero). I want the order of assignments to be in the same order as they appear in the declaration.
In this particular example, the sequence would simply be 0, 1 and 2. Is there an expression I can use to achieve this? Or is it only possible by manually typing out this by hand?
I want to have two hashable implementations, so I can establish all possible varieties or simply how many cases I have.
enum Score: {
case snap(Rank) // 6 varieties
case double(Power) // 4 varieties
case highFive
var value: Int {
// ...
}
}
enum Rank: Int {
//..
}
enum Power: Int {
// ..
}
It seems this is not possible.
I either choose to maintain two enums that are identical except one has associated types and the other does not.
Or I manually implement the solution.
Manual
So for a poker game, I would establish an order of importance for each hand, as per the rules of Texas Hold'em.
private extension Hand {
var precedence: Int {
switch self {
case .highCard:
return 0
case .pair:
return 1
case .twoPair:
return 2
case .threeKind:
return 3
case .straight:
return 4
case .fourKind:
return 5
case .flush:
return 6
case .fullHouse:
return 7
case .straightFlush:
return 8
case .royalFlush:
return 9
}
}
}
When the above is in place, I can then produce a toggle.
extension Hand: CaseIterable {
public static var allCases: [Self] {
let ranks = Rank.allCases
return ranks.map(highCard) +
ranks.map(pair) +
ranks.map(twoPair) +
ranks.map(threeKind) +
ranks.map(straight) +
ranks.map(fourKind) +
ranks.map(flush) +
ranks.map(fullHouse) +
ranks.map(straightFlush) +
[royalFlush]
}
/// Establish every unique case.
/// - Parameter ignore: If true, do not unique by rank.
/// - Returns: Every possible case, with or without rank as a uniquing restriction.
public static func allCases(ignoringRank: Bool) -> [Self] {
switch ignoringRank {
case true:
var tally = Set<Int>()
return Self.allCases.filter {
switch tally.contains($0.precedence) {
case true:
return false
case false:
tally.insert($0.precedence)
return true
}
}
case false:
return Self.allCases
}
}
}
The following is now possible.
private extension Hand {
static var assessments: [Assessable.Type] {
allCases(ignoringRank: true).map {
$0.assessment
}
}
private var assessment: Assessable.Type {
switch self {
case .highCard:
return HighCardAssessor.self
case .pair:
return PairAssessor.self
case .twoPair:
return TwoPairAssessor.self
case .threeKind:
return ThreeKindAssessor.self
case .straight:
return StraightAssessor.self
case .fourKind:
return FourKindAssessor.self
case .flush:
return FlushAssessor.self
case .fullHouse:
return FullHouseAssessor.self
case .straightFlush:
return StraightFlushAssessor.self
case .royalFlush:
return RoyalFlushAssessor.self
}
}
}
An assessor is a type that implements evaluate(cards:) to determine if a hand exists. So being able to loop like this is useful.

Value of type 'CalcButton' has no member 'rawValue'

I have a problem.
I am a beginner in programming and searched for how to make a calculator on youtube and tried to do it my self. I do exactly as he did but i get an error message and can't figure out what the problem is and have searched all over the forum for help but don't see any answers! I'm using Xcode on my macbook and are using swift.
here is the code:
enum CalcButton {
case one
case two
case three
case four
case five
case six
case seven
case eight
case nine
case zero
case dividera
case multiplicera
case subtrahera
case addera
case likamed
case clear
case procent
case plusminus
}
struct ContentView: View {
let buttons: [[CalcButton]] = [
[.seven, .eight, .nine]
]
var body: some View {
ZStack {
Color.black.edgesIgnoringSafeArea(/*#START_MENU_TOKEN#*/.all/*#END_MENU_TOKEN#*/)
VStack {
// Text Display
HStack {
Spacer()
Text("0")
.bold()
.font(.system(size: 64))
.foregroundColor(.white)
// Knappar
ForEach(buttons, id: \.self) { row in
ForEach(row, id: \.self) { item in
Button(action: {
}, label: {
Text(item.rawValue)
})
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}```
In your code you are calling item.rawValuebut your enum CalcButtons has no raw value associated with it so this property doesn’t exists for the enum.
You need to assign a raw value and judging by how it is used it should be String so change your enum declaration to
enum CalcButtons: String {
<same code as before>
}
You can read more about enum raw values here but in short what happens is that each case item in your enum gets a string value assigned to it that is the same as the item name.

Presenting views using associated value of enum case

I'm passing an object of a coredata model(ItemModel) using enums like this
.sheet(item: $activeSheet, onDismiss: { self.activeSheet = nil }) { item in
switch item {
case .newDoc:
NewDocumentView(ref: nil).environment(\.managedObjectContext, context)
case .detailFolder(let data):
DetailedFolderView(item: data, dirName: data.wrappedName, updater: viewUpdater).environment(\.managedObjectContext, context)
case .detailDoc(let file):
DetailDocumentView(item: file, fileName: file.wrappedItemName)
.environment(\.managedObjectContext, context)
}
}
but while i try to update the ItemModel object in the DetailDocumentView using the managed object context after saving and dismissing the view the parent view isnt updated, the view updates only after restarting the app
Can anyone suggest a way to update the parent view after updating the object of the coredata model(ItemModel) being passed in DetailDocumentView. Any suggestions are welcome :)
Been stuck on this issue for hours, tried using observable objects, tried using a publisher when context is updated, but noting has worked so far :(
Heres a reference of the code used when tapped on a file to present DetailDocumentView
/// creates a grid to display data
/// - Parameters:
/// - geometry: setup dimension for the grid view
/// - folders: files required
/// - Returns: returns a grid
private func gridView(_ geometry: GeometryProxy, files: FetchedResults<ItemModel>) -> some View {
QGrid(files,
columns: 2,
columnsInLandscape: 0,
vSpacing: 20,
hSpacing: 35,
vPadding: 10,
hPadding: 10,
isScrollable: false,
showScrollIndicators: false) { file in
FileItemView(item: file)
.environment(\.managedObjectContext, context)
.onTapGesture {
self.activeSheet = .detailDoc(file: file)
}
}
}
The enum case I used to present multiple sheet is below
/// for presenting sheets
enum HomeViewActiveSheet: Any {
case newDoc
case detailFolder(folder: FolderModel)
case detailDoc(file: ItemModel)
}
// so that it can be used in the .sheet init
extension HomeViewActiveSheet: Identifiable {
var id: ObjectIdentifier {
ObjectIdentifier(Self.self)
}
}
And I declare it in the parent class as this:
#State private var activeSheet: HomeViewActiveSheet? = .none

What is the easiest way to test if an enum-based variable is *not* equal to a specific case with an associated value?

We have the following enum and variable
enum DisplayState{
case loading
case loaded(ViewModel)
case noResults
case error
}
var displayState:DisplayState = .loading
We want to test if we're in any state other than loaded.
Since there is an associated value, this of course doesn't work...
if displayState != .loaded {
// Do something
}
But I'm hoping to find something else besides either of these...
switch displayState{
case .loaded: break
default: // Do something
}
or
if case .loaded = displayState {} else {
// Do something
}
So what's the simplest way to test for this case?
Try that:
enum DisplayState {
case loading
case loaded(ViewModel)
case noResults
case error
var isLoaded: Bool {
switch self {
case .loaded:
return true
default:
return false
}
}
}
var displayState: DisplayState = .loading
if displayState.isLoaded {
// code
}

In didSet for an enum property in Swift is it possible to check if the new value is the same as the old one? [duplicate]

This question already has an answer here:
How may I test the equivalency of enumeration cases with associated values in Swift 4
(1 answer)
Closed 4 years ago.
Given the following example:
enum ViewState {
case idle
case loading
case caseWithAssociatedValue(String)
}
class View {
private var state: ViewState = .idle
func setState(to state: ViewState) {
guard state != self.state else { return }
self.state = state
}
}
I can't compare two properties of type ViewState and I can't use a raw value to compare as one of my cases has an associated value.
What I'm looking for is a way to check if the new value for state a new value or the same as the current value. Is this possible?
Use willSet and do something like this
enum State : Equatable {
case idle
case active
case done(String)
}
class test {
var x: State {
willSet {
if x != newValue {
print("\(x) -> \(newValue)")
}
}
}
init(_ x: State) {
self.x = x
}
}
let t = test(State.idle)
t.x = State.active
t.x = State.done("We're done")
Output is
idle -> active
active -> done("We\'re done")