ui-mapbox
ui-mapbox copied to clipboard
Layer layout with "icon-text-fit-padding" not working in ios
Hello I am currently evaluating this library for a project and noticed some support differences between ios and android.
For this case, I am able to apply "icon-text-fit": "width" to resize icon to the text size for both environment but when I provide "icon-text-fit-padding" I get an error which breaks layer rendering in ios.
` this.mapbox .addLayer({ id: "store-locations", type: "symbol", source: "stores", filter: ["has", "label_en"], minzoom: 0, maxzoom: 20,
layout: {
"icon-opacity": ["case", ["has", "label_en"], 1, 0],
"text-field": [
"case",
["has", "label_en"],
["get", "label_en"],
"",
],
"icon-image": ["case", ["has", "label_en"], "box2", ""],
"icon-text-fit": "width",
"icon-text-fit-padding": [0, 0, 0, 0],
"icon-size": 1,
"text-font": ["Open Sans Regular", "Arial Unicode MS Regular"],
"text-size": 12,
},
})
.catch((e) => {
console.log(e);
});`
This is the error in IOS
Error: -[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0xac6605cc1e5c96e6
I suspect that should be a supported attribute in ios as if I provide a wrong format I get an error that the format needs to be an array with 4 items.
@MarkOdey i dont really use mapbox anymore though i might have a fix.
Could you try to replace the content of node_modules/@nativescript-community/ui-mapbox/layers/parser/property-parser.ios.js with this?
import { Color } from '@nativescript/core';
function toCamelCase(s) {
return s.replace(/([-_][a-z])/gi, ($1) => $1.toUpperCase().replace('-', '').replace('_', ''));
}
const styleExtras = {
iconTextFitPadding: {
iosType: 'edgeinsets',
},
iconOffset: {
iosType: 'vector',
},
textOffset: {
iosType: 'vector',
},
lineOffset: {
iosType: 'vector',
},
fillTranslate: {
iosType: 'vector',
},
lineTranslate: {
iosType: 'vector',
},
iconTranslate: {
iosType: 'vector',
},
textTranslate: {
iosType: 'vector',
},
circleTranslate: {
iosType: 'vector',
},
fillExtrusionTranslate: {
iosType: 'vector',
},
};
const keysMap = {
'circle-pitch-scale': 'circleScaleAlignment',
'circle-translate': 'circleTranslation',
'circle-translate-anchor': 'circleTranslationAnchor',
'fill-antialias': 'fillAntialiased',
'fill-translate': 'fillTranslation',
'fill-translate-anchor': 'fillTranslationAnchor',
'icon-allow-overlap': 'iconAllowsOverlap',
'icon-keep-upright': 'keepsIconUpright',
'icon-ignore-placement': 'iconIgnoresPlacement',
'icon-image': 'iconImageName',
'icon-rotate': 'iconRotation',
'icon-rotate-alignment': 'iconRotationAlignment',
'icon-translate': 'iconTranslation',
'icon-translate-anchor': 'iconTranslationAnchor',
'icon-size': 'iconScale',
'line-translate': 'lineTranslation',
'line-translate-anchor': 'lineTranslationAnchor',
'line-dasharray': 'lineDashPattern',
'text-allow-overlap': 'textAllowsOverlap',
'text-field': 'text',
'text-font': 'textFontNames',
'text-justify': 'textJustification',
'text-ignore-placement': 'textIgnoresPlacement',
'text-keep-upright': 'keepsTextUpright',
'text-max-angle': 'maximumTextAngle',
'text-max-width': 'maximumTextWidth',
'text-rotate': 'textRotation',
'text-rotate-alignment': 'textRotationAlignment',
'text-size': 'textFontSize',
'text-translate': 'textTranslation',
'text-translate-anchor': 'textTranslationAnchor',
'raster-hue-rotate': 'rasterHueRotation',
'raster-resampling': 'rasterResamplingMode',
'raster-brightness-min': 'maximumRasterBrightness',
'raster-brightness-max': 'minimumRasterBrightness'
};
function transformValue(key, value, _styleType) {
if (_styleType === 'color') {
const color = value instanceof Color ? value : new Color(value);
return color.ios;
}
else if (_styleType === 'vector') {
const vector = CGVectorMake(value[0], value[1]);
return NSExpression.expressionWithMGLJSONObject(NSValue.valueWithCGVector(vector));
}
else if (_styleType === "edgeinsets") {
const edgeInsets = new UIEdgeInsets({
top: value[0],
left: value[1],
bottom: value[2],
right: value[3],
});
return NSExpression.expressionWithMGLJSONObject(NSValue.valueWithUIEdgeInsets(edgeInsets));
}
else {
switch (key) {
case 'raster-resampling':
if (value === 'linear') {
return 0;
}
else if (value === 'nearest') {
return 1;
}
else {
return value;
}
default:
return value;
}
}
}
export class PropertyParser {
static parsePropertiesForLayer(propertiesObject) {
const nProperties = {};
if (propertiesObject) {
Object.keys(propertiesObject).forEach((k) => {
var _a;
const actualKey = keysMap[k] || toCamelCase(k);
const value = propertiesObject[k];
const rValue = transformValue(k, value, (_a = styleExtras[k]) === null || _a === void 0 ? void 0 : _a.iosType);
if (Array.isArray(value)) {
nProperties[actualKey] = NSExpression.expressionWithMGLJSONObject(rValue);
}
else {
nProperties[actualKey] = NSExpression.expressionForConstantValue(rValue);
}
});
}
return nProperties;
}
static propertyValueFromLayer(layer, key) {
const actualKey = keysMap[key] || toCamelCase(key);
const nValue = layer[actualKey];
if (!nValue) {
return null;
}
if (nValue.expressionType === 0) {
if (nValue.constantValue instanceof UIColor) {
return Color.fromIosColor(nValue.constantValue);
}
else {
return nValue.constantValue;
}
}
else {
const expressionObj = nValue.mgl_jsonExpressionObject;
const data = NSJSONSerialization.dataWithJSONObjectOptionsError(expressionObj, 0);
const expression = NSString.alloc().initWithDataEncoding(data, NSUTF8StringEncoding);
return JSON.parse(expression);
}
}
}
//# sourceMappingURL=property-parser.ios.js.map
If it works i ll make a new release
Hello Thank you very much for your help.
I tried to put padding with your changes and still no luck.
the layer doesn't render and outputs this error :
Error: -[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0xcce836faf54293da
Maybe I am misusing the edgeinsets data type.
Maybe I am unaware of a procedure for the changes to take effect.
Again thanks for your support.
@MarkOdey ok can you create a repro example repo so that I can test and fix?