1

I want to color my MGLSymbolStyleLayer feature icons based on multiple if conditions, which requires the use of MGL_IF, but I'm getting this runtime error: 'Unable to parse the format string...'

projectsLayer!.iconColor =
          NSExpression(format: "MGL_IF(location_name IN %@, %@, location_name = United States,  %@)",
                       uniqueLocations, savedColor, defaultColor)

Note, for something simple like this I can use a ternary operator and that's working fine for me. But I need to add multiple conditions for multiple colors and so I need to use MGL_IF or something similar.

1 Answers1

2

It appears that a regression in the Maps SDK caused by a change in Apple’s iOS/macOS SDK is causing this behavior with MGL_IF. As a workaround, you can either use the TERNARY() or MGL_MATCH() operators as outlined below:

TERNARY() only supports a single case. (MGL_IF​ is no different than TERNARY and is not necessary.) For multiple cases, you need to either nest TERNARY(foo = bar, 'A', TERNARY(bar = baz, 'B', 'C')):

coloredLayer.fillColor = NSExpression(format: "TERNARY(location_name = 'United States', %@, TERNARY(location_name = 'Russia', %@,))", UIColor.white, UIColor.green, UIColor.magenta)

Or use MGL_MATCH():

coloredLayer.fillColor = NSExpression(format: "MGL_MATCH(location_name, 'United States', %@, 'Russia', %@, 'Brazil', %@, 'Venezuela', %@, %@)", UIColor.white, UIColor.lightGray, UIColor.purple, UIColor.systemTeal, UIColor.yellow)

which will result in the United States being colored while, Russia colored light gray, Brazil colored purple, Venezuela colored teal and everything else colored yellow.

invaderzizim
  • 311
  • 1
  • 5
  • The nested ternary worked like a charm, thank you so much! I wasn't able to get the MGL_MATCH option working since my check isn't a simple equals comparison (I'm finding if the feature exists in an array). – Rodrigo Bell Apr 20 '20 at 23:09
  • @RodrigoBell — can you add any details on your problem of *finding if the feature exists in an array?* I am tracking a similar solution for styling features with NSExpression with values from an array. The array could be over 100 elements and creating the `MGL_MATCH` is getting unwieldy as we need to add many arguments to `MGL_MATCH`. Tracking the issue on github.com/roblabs/ios-map-ui/issues/11#issuecomment-673867235 – RobLabs Aug 14 '20 at 16:05
  • `TERNARY(… IN …, …, …)` is convenient even for many inputs, as long as there are only two outputs. If there are many outputs, you can either build up a format string (potentially fragile and insecure) or use the `NSExpression(forMGLMatchingKey:in:default:)` intializer. – Minh Nguyễn Aug 14 '20 at 17:45
  • This works for a binary color fill operation; red/gray in this case —  `layer.fillColor = NSExpression(format: "TERNARY(name in %@, %@, %@)", arrayOfNames, UIColor.red, UIColor.gray)` – RobLabs Aug 15 '20 at 20:21