Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

ios - SwiftUI - Wrap ListStyle in an enum and translate it back to ListStyle

I'm working on a library, so I want it to be as easily configurable as possible. I put all the configurable options inside SupportOptions.

struct SupportOptions {
    var text: String = ""
    var listStyle: CustomListStyle = CustomListStyle.insetGroupedListStyle
}
extension SupportOptions {
    
    /**
     Enum wrapper for `ListStyle`
     */
    enum CustomListStyle {
        case defaultListStyle
        case plainListStyle
        case groupedListStyle
        case insetGroupedListStyle
        case insetListStyle
        case sidebarListStyle
    }
}

I'm following @Sweeper's suggestion to use an enum to store ListStyle, so that's what CustomListStyle is for. But I need to translate CustomListStyle to an actual ListStyle. This is what I have so far:

extension List {
    func getStyle<S>(listStyle: SupportOptions.CustomListStyle) -> S {
        switch listStyle {
        case .defaultListStyle:
            return DefaultListStyle() as! S
        case .plainListStyle:
            return PlainListStyle() as! S
        case .groupedListStyle:
            return GroupedListStyle() as! S
        case .insetGroupedListStyle:
            return InsetGroupedListStyle() as! S
        case .insetListStyle:
            return InsetListStyle() as! S
        case .sidebarListStyle:
            return SidebarListStyle() as! S
        }
    }
}

But when I use it, I get

Generic parameter 'S' could not be inferred

struct ContentView: View {
    let options = SupportOptions(listStyle: .defaultListStyle)
    
    let data = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen"]
    var body: some View {
        List { /// Error! Generic parameter 'S' could not be inferred
            ForEach(data, id: .self) { word in
                Text(word)
            }
        }
        .getStyle(listStyle: options.listStyle)
    }
}

I tried adding a placeholder type S, but the error stayed the same...

struct ContentView<S>: View where S: ListStyle {
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can return an opaque type (some View) instead:

extension List {
    @ViewBuilder
    func listStyle(for customListStyle: SupportOptions.CustomListStyle) -> some View {
        switch customListStyle {
        case .defaultListStyle:
            listStyle(DefaultListStyle())
        case .plainListStyle:
            listStyle(PlainListStyle())
        case .groupedListStyle:
            listStyle(GroupedListStyle())
        case .insetGroupedListStyle:
            listStyle(InsetGroupedListStyle())
        case .insetListStyle:
            listStyle(InsetListStyle())
        case .sidebarListStyle:
            listStyle(SidebarListStyle())
        }
    }
}
List {
    // ...
}
.listStyle(for: options.listStyle)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...