Home > Net >  Why can't one iterate through enum data within a SwiftUI view?
Why can't one iterate through enum data within a SwiftUI view?

Time:10-06

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.

CodePudding user response:

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).

CodePudding user response:

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 }
    
}
  • Related