24

Say I have some enum, Channel, filled with sample property data:

enum Channel: CaseIterable {
  case abc
  case efg
  case hij
  
  var name: String {
    switch self {
    case .abc:  return "ABC"
    case .efg:  return "EFG"
    case .hij:  return "HIJ"
    }
  }
}

extension Channel: Identifiable {
  var id: Self { self }
}

And some view implementation to fill said content with:

struct ChannelHome: View {
  var body: some View {
    VStack {
      ForEach(Channel.allCases) { channel in
        NavigationLink(destination: ChannelDetail(channel)) {
          Text(channel.name)
        }
      }
    }
  }
}   // big closure yikes

Why doesn't this work? Is this due to the nature of enums not having static properties and SwiftUI being declarative? Are there ways around this? Such as:

struct ChannelData {
  static let channels: [Channel] = [.abc, .efg, .hij]
  // or
  static func getChannels() -> [Channel] {
    var channelArray: [Channel]
    for channel in Channel.allCases {
      channelArray.append(channel)
    }
    return channelArray
  }
}

Or, more preferably, are there better practices for presenting small data sets like these in a SwiftUI view? I like being able to implement a visual UI of my properties for when I'm debugging, as a whole, at runtime (closer to the production stage).

I apologies in advance for the question, I am just getting into it with SwiftUI.

3
  • What exactly does not work for you? All seems works fine here (Xcode 13 / iOS 15). Maybe you just forgotten to wrap ChannelHome's content into NavigationView to make links working? Commented Oct 5, 2021 at 18:40
  • You code works for me in Xcode 13 on an iOS 15 simulator. It displays the the letters on the screen. (I removed the NavigationLink as you didn't provide ChannelDetail) Commented Oct 5, 2021 at 18:42
  • By the way, your getChannels method doesn't actually do anything, at all. Commented Oct 7, 2021 at 16:04

2 Answers 2

34

Here are 2 simple ways for you, but not sure where can be helpful for you because with enum you cannot update ForEach elements, but it has a use case for showing data!

First way without any Identifiable id:

struct ContentView: View {        
    var body: some View {            
        ForEach(TestEnum.allCases, id: \.rawValue) { item in                 
            Text(item.rawValue)                
        }
    }        
}

enum TestEnum: String, CaseIterable { case a, b, c }

with Identifiable id that conforms to Identifiable protocol, you can cut , id: \.id even:

struct ContentView: View {
    var body: some View {
        ForEach(TestEnum.allCases, id: \.id) { item in
            Text(item.rawValue)
        }
    }
}

enum TestEnum: String, CaseIterable, Identifiable { case a, b, c
    var id: String { return self.rawValue }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Space! The question is not about space! It is about enum and ForEach! Take the idea about those!
Forget format! The idea is important
"Forget format!" No thanks. It's how you communicate ideas, which is usually where the bottleneck is.
You can also do id: \.self and then item.rawValue
Pointing out that @Sentry.co's comment is great, as it removed the otherwise unused id field from the enum.
|
10

Either Xcode was getting hung up on cache errors or I am a fool (probably the latter). Regardless, the issue seems to have been resolved with the following Identifiable extension to your enum, as well as a good ol' derived data purge and clean:

extension Channel: Identifiable {
  var id: Self { self }
}

I seem to have confused this issue with another long-time issue that I've constantly run into; mostly regarding enums and their distaste for storing static data (as is simply just the nature of their fast and lite structure).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.