Каждый раз, когда мы загружаем изображения из Интернета, есть вероятность, что загрузка не удалась. Для лучшего взаимодействия с пользователем важно иметь готовый механизм заполнителя. В этом посте я покажу вам, как я расширил свой форк Xamarin.Forms.Nuke для достижения этой цели на iOS.
Что такое Xamarin.Forms.Nuke?
Xamarin.Forms.Nuke - это реализация Xamarin.Forms Nuke, одной из самых продвинутых библиотек изображений для iOS на сегодняшний день. Реализация Xamarin.Forms в значительной степени ориентирована только на кеширование, в то время как исходная библиотека имеет множество дополнительных функций. Я узнал об этой библиотеке, когда начал искать альтернативу кэшированию изображений через Akavache, который я использовал раньше (я никогда не писал об этой части, потому что она не была готова к этому, tbh).
Зачем нужно расширять библиотеку?
В настоящее время библиотека делает только одно (очень хорошо) - обрабатывает кеширование веб-изображений. Он использует настройки по умолчанию собственной библиотеки Nuke. Реализация Xamarin.Forms перезаписывает ImageSourceHandler для UriImageSource и FileImageSource (необязательно), но случай загрузки заполнителя не предусмотрен в исходной версии. Поскольку у меня есть несколько сценариев, в которых может пригодиться заполнитель, я решил расширить библиотеку - и с этого момента поддерживать ее собственный форк. (Может быть, тоже будет запрос на перенос к первоисточнику).
Покажи мне наконец код!
Для нашего расширения мы модифицируем класс FormsHandler, а также класс ImageSourceHandler. Давайте сначала посмотрим на класс FormsHandler. Мы добавляем новое свойство для заполнителя:
public static ImageSource PlaceholderImageSource { get; private set; }
Я выбрал класс FormsHandler, потому что установка заполнителя - это глобальная вещь (в моих сценариях ваш пробег может отличаться). Это уже все, что есть в классе FormsHandler, поэтому давайте взглянем на класс ImageSourceHandler.
Поскольку мы используем значение по умолчанию Xamarin.Forms ImageSourceHandler для изображения ресурса (это StreamImageSource) и FontImageSource, нам нужно сначала добавить для них статические поля:
private static readonly StreamImagesourceHandler DefaultStreamImageSourceHandler = new StreamImagesourceHandler(); private static readonly FontImageSourceHandler DefaultFontImageSourcehandler = new FontImageSourceHandler();
Теперь давайте реализуем загрузку заполнителя отдельным методом:
private static Task<UIImage> LoadPlaceholderAsync()
{
switch (FormsHandler.PlaceholderImageSource)
{
case StreamImageSource streamImageSource:
FormsHandler.Warn($"loading placeholder from resource");
return DefaultStreamImageSourceHandler.LoadImageAsync(streamImageSource);
case FontImageSource fontImageSource:
FormsHandler.Warn($"loading placeholder from Font");
return DefaultFontImageSourcehandler.LoadImageAsync(fontImageSource);
default:
FormsHandler.Warn($"no valid placeholder found");
return null;
}
}
Как видите, ничего сложного в этом методе нет. В зависимости от типа заполнителя, установленного в классе FormsHandler, мы вызываем реализацию по умолчанию Xamarin.Forms для изображения-заполнителя. Давайте применим этот код, изменив LoadImageAsync метод ImageSourceHandler:
public async Task<UIImage> LoadImageAsync(
ImageSource imageSource,
CancellationToken cancellationToken = new CancellationToken(),
float scale = 1)
{
var result = await NukeHelper.LoadViaNuke(imageSource, cancellationToken, scale);
if (result == null)
result = await LoadPlaceholderAsync();
return result;
}
Поскольку нам нужно знать, может ли класс Nukehelper загрузить изображение, мы уже запускаем код, ожидая его на этом уровне. Если результат равен нулю, мы загружаем изображение-заполнитель с помощью нашего ранее реализованного метода. Это все, что нам нужно сделать в нашем разветвленном репозитории Xamarin.Forms.Nuke.
Как использовать его в своем проекте Xamarin.Forms - iOS
Сначала клонируйте мою вилку (или, если хотите) репозитория Xamarin.Forms.Nuke, импортируйте ее в свое решение Xamarin.Forms и ссылайтесь на нее в своем проекте iOS. Как только это будет сделано, нам нужно инициализировать библиотеку Nuke (как в исходном коде) в методе AppDelegate‘s FinishedLaunching:
Xamarin.Forms.Nuke.FormsHandler.Init(true, false);
Второй шаг - определить источник изображения-заполнителя. FontImageSource следует определять после LoadApplication метода. Таким образом вы можете Xamarin.Forms загрузить шрифт как ресурс.
//Resource image
Xamarin.Forms.Nuke.FormsHandler.PlaceholderFromResource("CachedImageTest.MSicc_Logo_Base_Blue_1024px_pad25.png", Assembly.GetAssembly(typeof(MainViewModel)));
//FontImageSource
Xamarin.Forms.Nuke.FormsHandler.PlaceholderFromFontImageSource(new FontImageSource
{
Glyph = CachedImageTest.Resources.MaterialDesignIcons.ImageBroken,
FontFamily = "MaterialDesignIcons",
Color = Color.Red
});
Теперь используйте элемент управления Xamarin.Forms Image, как всегда. Если изображение из Интернета не может быть загружено, вы увидите заполнитель, как в этих двух примерах:

С помощью нескольких дополнений к библиотеке Xamarin.Forms.Nuke мы реализовали механизм заполнителя для изображений, которые не могут быть загружены. Как всегда, я надеюсь, что этот пост будет полезен для некоторых из вас. Теперь, когда у меня есть реализация для iOS быстрого кэширования изображения с загрузкой заполнителя, я перейду к Android, где я попытаюсь добиться того же с помощью библиотеки Glidex.Forms и расширить ее, чтобы загрузить заполнитель. После реализации будет и полный образец. Следите за новостями!
До следующей публикации, желаю всем счастливого кодирования!
Сообщение Расширение Xamarin.Forms.Nuke на iOS для загрузки заполнителя для изображений, которые не загружаются впервые появилось в Блоге MSicc.