swiftuiuiimagecarplay

CarPlay SwiftUI no applying color to non-system UIImage


In an Apple CarPlay CPGridTemplate with several buttons, the buttons from a system UIImage are tinted cyan by the system, while the buttons from a custom SVG stay black. All combinations of .withRenderingMode(...), .withTintColor(.cyan) to get the custom UIImage displayed in cyan color are to no avail.

I realized when I export the cart.fill symbol from Apple SF-Symbols as an SVG and import it in Xcode as a custom SVG asset, it stays back as well.

What is the reason? How to get the custom SVG tinted by CarPlay same as the system symbols?

// This Button is displayed in CYAN
let cyanButton = CPGridButton(titleVariants: [...],
                              image: UIImage(systemName: "cart.fill")!)
                              { button in ... }

// This Button is displayed in BLACK
let blackButton = CPGridButton(titleVariants: [...],
                               image: UIImage(named: "playground.fill")!)
                               { button in ... }

let gridTemplate = CPGridTemplate(title: ...), gridButtons: [cyanButton, blackButton])

Custom SVG UIImage in CPGridTemplate stay black

I tried:

UIImage(named: "playground.fill")!.withRenderingMode(.alwaysTemplate)
UIImage(named: "playground.fill")!.withRenderingMode(.alwaysOriginal)
UIImage(named: "playground.fill")!.withRenderingMode(.alwaysTemplate).withTintColor(.cyan)
UIImage(named: "playground.fill")!.withRenderingMode(.alwaysOriginal).withTintColor(.cyan)

Any idea is highly welcome.


Solution

  • Using PNG images instead of SVG solved my problem. Best results for grid icons looking same like SF Symbol system images I get when I copy the custom symbols from SF Symbols for image@3x as:

    Symbol Style: Light
    Copy as: PNG
    Point size: 40 pt
    Pixel scale: 1
    Symbols Scale: medium

    If you provide image@3x only, with these parameters the icon size looks matching to system icons in CarPlay Standard, Widescreen and Minimum.

    Make sure CarPlay can apply the right color depending on light or dark mode by using withRenderingMode(.alwaysTemplate):

    CPGridButton(titleVariants: ...,
                 image: UIImage(named: "...")!
                    .withRenderingMode(.alwaysTemplate))
                { button in
                  ...
                }
    )