Can an Enum Contain Another Enum Values in Swift

Can an enum contain another enum values in Swift?

Details

  • Swift 4, 3
  • Xcode 10.2.1 (10E1001), Swift 5 (Last revision of this post)

Solution

enum State {
case started, succeeded, failed
}

enum ActionState {
case state(value: State), cancelled
}

class Action {
var state: ActionState = .state(value: .started)
func set(state: State) { self.state = .state(value: state) }
func cancel() { state = .cancelled }
}

Full Sample

Do not to forget to paste the solution code

import Foundation

extension Action: CustomStringConvertible {
var description: String {
var result = "Action - "
switch state {
case .state(let value): result += "State.\(value)"
case .cancelled: result += "cancelled"
}
return result
}
}

let obj = Action()
print(obj)
obj.set(state: .failed)
print(obj)
obj.set(state: .succeeded)
print(obj)
obj.cancel()
print(obj)

Result

//Action - State.started
//Action - State.failed
//Action - State.succeeded
//Action - cancelled

How can i get an enum value based on other enum in Swiftui?

You have two ways to do this. The first is to create a property on your enum that returns a value from the other. The second is to create an init on the enum that uses the other as the property.

Example of the first:

enum GenderString: String {
case man = "man"
case woman = "woman"

var icon: GenderIcon {
switch self {
case .man: return .man
case .woman: return .woman
}
}
}

enum GenderIcon: String {
case man = "‍♂️"
case woman = "‍♀️"
}

var gender: GenderString = .man
gender.icon.rawValue // ‍♂️

Example of the second.

enum GenderString: String {
case man = "man"
case woman = "woman"
}

enum GenderIcon: String {
case man = "‍♂️"
case woman = "‍♀️"

init(gender: GenderString) {
switch gender {
case .man: self = .man
case .woman: self = .woman
}
}
}

var gender: GenderString = .woman
var icon = GenderIcon(gender: gender)
icon.rawValue // ‍♀️

However, because you can add properties to enums, you can skip having a separate enum for the icon and simplify your example into:

enum Gender: String {
// Implicitly uses the case name as the raw string value
case man
case woman

var icon: String {
switch self {
case .man: return "‍♂️"
case .woman: return "‍♀️"
}
}
}

var man: Gender = .man
man.icon // ‍♂️

Swift 5 - Enum inside of enum

If I understand your question correctly, you want to access associated types' properties. You can add a new property to your MaterialClassification enum and use it to access your cases.

Something like this should work

var type: String? {

switch self {
case .clay(let clay):
return clay.clayType
case .flux(let flux):
return flux.fluxType
case .stain(let stain):
return stain.stainType
case .glassFormer, .accessoryMaterial, .all:
return nil
}
}

Is it possible group & represent multiple cases as another case within an enum in Swift?

You can used nested Enum and a case with parameter

enum Devices {
case phone(iPhone)
case tablet(iPad)

enum iPhone {
case phone7
case phoneX
}

enum iPad {
case mini
case pro
}
}

let randomDevice = Devices.phone(.phone7)

switch randomDevice {
case .phone:
print("Its a phone")
default:
break
}

// prints "Its a phone"

How can I create a enum from another enum in Swift?

To the best of my knowledge, no, but you can do this:

enum Bar: Int {
case unknown
case secondCase
}

enum Foo: Int {
case bar(Bar)
case thirdCase
}

You'd have to implement your own Equatable, Hashable, etc., conformance, but it could be done. Enums are not designed for it, though, and neither is the language.

In the future, someone could propose this on the Swift Forums, where the community makes proposals to evolve the language.

Swift - Passing different enum types for same variable to a class

For applying abstraction, you could use protocol, as follows:

protocol Menu {}

enum Menu1: String, Menu {
case option1 = "Option 01 From Menu 01"
case option2 = "Option 02 From Menu 01"
case option3 = "Option 03 From Menu 01"
case option4 = "Option 04 From Menu 01"
case option5 = "Option 05 From Menu 01"
}

enum Menu2: String, Menu {
case option1 = "Option 01 From Menu 02"
case option2 = "Option 02 From Menu 02"
case option3 = "Option 03 From Menu 02"
case option4 = "Option 04 From Menu 02"
case option5 = "Option 05 From Menu 02"
}

By implementing this, you are able to declare arrays of Menu type, which include both of the enums:

let myMenu1Array: [Menu1] = [.option1, .option2, .option5]
let myMenu2Array: [Menu2] = [.option1, .option3, .option4]

For instance, a function that takes a parameter as array of Menus should work:

func handleMenu(_ menuArray: [Menu]) {
if let menu1Array = menuArray as? [Menu1] {
print("Menu 1 Detected!")

// you could iterate through it for instance...
for option in menu1Array {
print(option.rawValue)
}

return
}

if let menu2Array = menuArray as? [Menu2] {
print("Menu 2 Detected!")

// you could iterate through it for instance...
for option in menu2Array {
print(option.rawValue)
}

return
}
}

The output would be:

handleMenu(myMenu1Array)
/*
Menu 1 Detected!
Option 01 From Menu 01
Option 02 From Menu 01
Option 05 From Menu 01
*/

handleMenu(myMenu2Array)
/*
Menu 2 Detected!
Option 01 From Menu 02
Option 03 From Menu 02
Option 04 From Menu 02
*/

So, if you have a property in a class that should represents a menu, you could declare it as a type of Menu:

class  MyClass {
...

var menu: Menu?

...
}

Swift enum inheritance

In Swift language, we have Structs, Enum and Classes. Struct and Enum are passed by copy but Classes are passed by reference. Only Classes support inheritance, Enum and Struct don't.

So to answer your question, you can't have inheritance with Enum (and Struct types). Have a look here:

stackOverflow difference classes vs structs



Related Topics



Leave a reply



Submit