Home > Software engineering >  Do not display a color if there is no color name (SwiftUI)
Do not display a color if there is no color name (SwiftUI)

Time:03-23

I get the name of the frame color for the picture from Model() the color I take from colorSet

struct Model: Identifiable {
    
    let id = UUID()
    let image: String
    let colorSet: String

}

extension Model {
    
    static func AllModel() -> [Model] {
        
        return [
            //1
            Model(image: "folder", colorSet: "YELLOW"),
            //2
            Model(image: "folder.fill",  colorSet: "")
            
        ]
        
    }
}

But if the colorSet doesn't have a color name because it's not needed, I get an error enter image description here

how to make that if a color name is not in the colorSet, then nothing is displayed

full code

struct Model: Identifiable {
    
    let id = UUID()
    let image: String
    let colorSet: String

}

extension Model {
    
    static func AllModel() -> [Model] {
        
        return [
            //1
            Model(image: "folder", colorSet: "YELLOW"),
            //2
            Model(image: "folder.fill",  colorSet: "")
            
        ]
        
    }
}


struct Im: View {
    
    let model = Model.AllModel()
    
    var body: some View {
        HStack {
        ForEach(model) { model in

           CellView(model: model)
        }
        
        }
    }
}


struct CellView: View {

    
    let model: Model
    
    var body: some View {

        Image(systemName: model.image)
            .resizable()
            .scaledToFit()
            .frame(width: 40, height: 40)
            .padding()
            .overlay(RoundedRectangle(cornerRadius: 9)
            .stroke(Color(model.colorSet), lineWidth: 5))

    }

    
}

enter image description here

CodePudding user response:

Just to be clear:

extension Model {
    
    static func AllModel() -> [Model] {
        return [
            //1
            Model(image: "folder", colorSet: "YELLOW"),
            //2
            Model(image: "folder.fill",  colorSet: "CLEAR")
        ]
    }
}

Set a "CLEAR" colorSet like this:

Image showing how to set clear color

As a result, you would get this:

Image showing result of code with yellow frame and clear frame

Edit:

Since your are ALSO displaying the name of the color below the icon, all you need to do is use a ternary to see if colorSet == "CLEAR" and then substitute an empty string for it like this:

struct CellView: View {
    let model: Model
    
    var body: some View {
        VStack {
        Image(systemName: model.image)
            .resizable()
            .scaledToFit()
            .frame(width: 40, height: 40)
            .padding()
            .overlay(RoundedRectangle(cornerRadius: 9)
            .stroke(Color(model.colorSet), lineWidth: 5))
            // Put a ternary in the Text() to test whether you have "CLEAR"
            Text(model.colorSet == "CLEAR" ? "" : model.colorSet)
        }
    }
}

CodePudding user response:

I would make your model richer so your view is simpler

struct Model: Identifiable {
    let id = UUID()
    let image: String
    let colorSet: String?  // optional named color
}

extension Model {
    static func AllModel() -> [Model] {
        return [
            //1
            Model(image: "folder", colorSet: "YELLOW"),
            //2
            Model(image: "folder.fill",  colorSet: nil)
        ]
    }

    // Computed property for the color
    var borderColor: Color {
        guard let colorSet = colorSet else {
            return .clear
        }

        return Color(colorSet)
    }

    // and e.g. for a name for showing in the UI
    var uiName: String {
        guard let colorSet = colorSet else {
            return "None"
        }

        return colorSet
    }
}

Then your view becomes

struct CellView: View {
    let model: Model

    var body: some View {
        Image(systemName: model.image)
            .resizable()
            .scaledToFit()
            .frame(width: 40, height: 40)
            .padding()
            .overlay(
                RoundedRectangle(cornerRadius: 9)
                    .stroke(model.borderColor, lineWidth: 5)
                )
    }
}

Similarly for text, with the name formatted for display in the model, not in the view.

  • Related