mapbox-maps-ios icon indicating copy to clipboard operation
mapbox-maps-ios copied to clipboard

Add `visibility` property to `Layer` protocol

Open devioustree opened this issue 4 years ago • 2 comments

New Feature

I would like to propose adding an additional property to the Layer protocol to make it easier to determine layer visibility:

var visibility: Value<Visibility> { get set }

Note that this is non-optional, which differs from the current implementation. The reason for this change is that all layers have an implicit visibility, so it is unclear what a nil value would represent.

Why

All existing implementations of the Layer protocol implement this property (ModelLayer is slightly different, but it would be trivial to conform with a computed property). By adding this to the protocol we can considerably simplify the code required to determine if an arbitrary Layer is visible:

// Existing code
switch layer.type {
case .background:
    return (layer as? BackgroundLayer)?.visibility == .constant(.visible)
case .circle:
    return (layer as? CircleLayer)?.visibility == .constant(.visible)
    ...
}

This would also solve the problem of ModelLayer being internal and LayerType being non-frozen which means any implementation of these needs to handle:

case .model:
    return ???
@unknown default:
    return ???

// or
default:
    return ???

devioustree avatar Jun 24 '21 16:06 devioustree

@devioustree thanks for the proposal. One clarifying question — are you trying to determine whether a layer is currently visible or just get the value of its visibility property. Note the subtle difference — if the value for visibility is an expression, just reading that value won't tell you if it's actually currently visible.

macdrevx avatar Oct 26 '21 02:10 macdrevx

Update here — since posting this, I learned that expressions aren't supported for visibility. The fact that the iOS layer APIs allow it is a mistake. We'll need to change that in our next major version.

The good news, though, is that this actually simplifies things for this specific use case: you can use the method Style.layerPropertyValue(for layerId: String, property: String) -> Any (available via mapView.mapboxMap.style) to get the current value for any layer property. Since it only requires a layer ID (not the layer type) and property name, and since the Layer protocol includes id, you could use this in a general way for any layer.

In this case, the property would just be the string "visibility", and the returned value should be a string. To convert it to Visibility, you can use Visibility(rawValue:)

macdrevx avatar Oct 29 '21 18:10 macdrevx

The visibility property was added to Layer in https://github.com/mapbox/mapbox-maps-ios/commit/79069cbded710a048adfbbb79d8d615790fb6662 Expression support for visibility landed in https://github.com/mapbox/mapbox-maps-ios/commit/ec842b9318ff0271b8704b29ce0c80025e32067c

OdNairy avatar Jan 15 '24 08:01 OdNairy