Home > Back-end >  SWIFT Changing colour of a shape depending on text from an array
SWIFT Changing colour of a shape depending on text from an array

Time:04-27

My aim is to display a different colour for each type of category within my array, there are over 10 categories so what I have now seems very inefficient, I have speculated using a function but have had no luck and cannot seem to find any online. my current code looks like -

if crime.category == "other-theft" {
                    RoundedRectangle(cornerRadius: 7.0)
                        .fill(Color.pink)
                        .frame(width: 50, height: 50)
                        .padding(.trailing)
                } else if crime.category == "possession-of-weapons" {
                    RoundedRectangle(cornerRadius: 7.0)
                        .fill(Color.red)
                        .frame(width: 50, height: 50)
                        .padding(.trailing)
                }  else if crime.category == "public-order" {
                    RoundedRectangle(cornerRadius: 7.0)
                        .fill(Color.red)
                        .frame(width: 50, height: 50)
                        .padding(.trailing)
                } else  if crime.category == "robbery" {
                    RoundedRectangle(cornerRadius: 7.0)
                        .fill(Color.cyan)
                        .frame(width: 50, height: 50)
                        .padding(.trailing)

Is there a smarter, less resource consuming way I can go about this?

CodePudding user response:

In the object representing crime declare a computed property

var categoryColor : Color {
    switch category {
        case "other-theft": return .pink
        case "possession-of-weapons", "public-order": return .red
        case "robbery": return .cyan
        ... other cases
    }
} 

Then create an extra view

struct CategoryView : View {
    let crime : Crime // assuming the type is called `Crime`

    var body: some View {
        RoundedRectangle(cornerRadius: 7.0)
            .fill(crime.categoryColor)
            .frame(width: 50, height: 50)
            .padding(.trailing)
    }
}

and replace the entire if - else chain with

CategoryView(crime: crime)

CodePudding user response:

Add an extension to your Crime type (or whatever it is named) and add a computed property that returns a colour for its category

extension Crime {
    var colorForCategory: Color {
        if self.category == "other-theft" return Color.pink
        if self.category == "possession-of-weapons" return Color.red
        // rest of categories

        return Color.black // default option
    }
}

and then you only need one rectangle

 RoundedRectangle(cornerRadius: 7.0)
                    .fill(crime.colorForCategory)
                    .frame(width: 50, height: 50)
                    .padding(.trailing)

I would strongly recommend though that you create an enum for your category and skip the strings.

enum CrimeCategory {
    case otherTheft
    case possesionOfWeapons
    // other cases
}

The computed property could then use a switch

extension Crime {
    var colorForCategory: Color {
        switch self.category {
        case otherTheft: 
             return Color.pink
        case possesionOfWeapons:
             return Color.red
        // rest of cases
       }
   }
}   
  • Related