0
votes

I have a Xamarin Forms application with a language selector that will be exposed to customers. When I switch language, I call a SetLocale() method to switch the current language.

public static void SetLocale(CultureInfo culture)
{
    Thread.CurrentThread.CurrentCulture = culture;
    Thread.CurrentThread.CurrentUICulture = culture;
    AppResources.Culture = culture;  
}

All textes are updated well (they come from resx files) but the images remains the one from the default application language (selected in the application settings) that I defined in the info.plist. enter image description here

I putted my images in the iOS project in Resources/.lproj following the xamarin documentation enter image description here

I bind them in the xaml file as usually

<Image Source="{Binding Image}"></Image>

How can I do to make the translation work for the images as well?

1
The default folder is named Base.lproj. Language-specific folders are named with the language or locale name . Make sure you named the area and language correctly .Lucas Zhang - MSFT
@LucasZhang-MSFT yes, it's working fine when I change the language in iOS app settings or when I setup the language programmatically with NSUserDefaults.StandardUserDefaults.SetValueForKey(NSArray.FromStrings(iOSLocale), new NSString("AppleLanguages")); NSUserDefaults.StandardUserDefaults.Synchronize(); but I need to restart the app to get the good image if I change the settings. My 2 testing languages are fr-CH and de-CH actually. I just see that the NSLocal is not updated when I set the new culture in CurrentCulture and CurrentUICulture, I also tried to change the DefaultThread cultureDemonia
I also tried to set a dependency in my iOS projet and to update the NsLocale.CurrentLocale but I didn't found how to do. I think the image bundle is loaded at the application start and not updated when dynamically switching the language.Demonia

1 Answers

0
votes

After many research, I couldn't find a way to do it with the native bundle of iOS.

I ended up by doing a markup extension following this tutorial and I customized it to have a fallback to a default locale if the image does not exists.

using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
    
namespace XamarinTest.Custom
{
    [ContentProperty(nameof(Source))]
    public class ImageResourceExtension : IMarkupExtension
    {
        public string Source { get; set; }
    
        public object ProvideValue(IServiceProvider serviceProvider)
        {
           if (Source == null)
               return null;
           var resourceName = string.Format("XamarinTest.Images.{0}.{1}", CultureInfo.CurrentUICulture.Name.Replace('-', '_'), Source);
           if (ResourceExists(resourceName))
               return ImageSource.FromResource(resourceName, typeof(ImageResourceExtension).GetTypeInfo().Assembly);
           return ImageSource.FromResource(string.Format("XamarinTest.Images.default.{0}", Source), typeof(ImageResourceExtension).GetTypeInfo().Assembly);
        }
    
        private string[] resourceNames;
    
        private bool ResourceExists(string resourceName)
        {
            if (resourceNames == null)
            {
                resourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
            }
            return resourceNames.Contains(resourceName);
        }
    }
}

I set the build action to EmbeddedResource for every images

project structure

Then in a view, I just add

xmlns:l="clr-namespace:XamarinTest.Custom"
...
<Image Source="{l:ImageResource qr.png}"
   HeightRequest="160"
   WidthRequest="160"></Image>