В Xamarin.Forms, Effect
может быть присоединено к View
. В моем случае вид отображает Image
. И эффект делает цветное «свечение» вокруг видимых пикселей изображения. XAML:
<Image Source="{Binding LogoImage}" ...>
<Image.Effects>
<effects:GlowEffect Radius="5" Color="White" />
</Image.Effects>
</Image>
Эффект реализован в виде подкласса RoutingEffect
:
public class GlowEffect : Xamarin.Forms.RoutingEffect
{
public GlowEffect() : base("Core.ImageGlowEffect")
{
}
...
}
На каждой платформе есть PlatformEffect
для реализации эффекта. Для iOS:
using ...
[assembly: ExportEffect(typeof(Core.Effects.ImageGlowEffect), "ImageGlowEffect")]
namespace Core.Effects
{
public class ImageGlowEffect : PlatformEffect
{
protected override void OnAttached()
{
ApplyGlow();
}
protected override void OnElementPropertyChanged( PropertyChangedEventArgs e )
{
base.OnElementPropertyChanged( e );
if (e.PropertyName == "Source") {
ApplyGlow();
}
}
private void ApplyGlow()
{
var imageView = Control as UIImageView;
if (imageView.Image == null)
return;
var effect = (GlowEffect)Element.Effects.FirstOrDefault(e => e is GlowEffect);
if (effect != null) {
CGRect outSize = AVFoundation.AVUtilities.WithAspectRatio( new CGRect( new CGPoint(), imageView.Image.Size ), imageView.Frame.Size );
...
}
}
...
}
}
Приведенный выше код работает, если Source
изменяется динамически: во время изменения Source
размер UIImageView
(Bounds
или Frame
) имеет размер , НО, если Источник установлен статически в XAML, этот лог c не запускается, поэтому единственный вызов ApplyGlow
происходит во время OnAttach
. К сожалению, во время OnAttach
, UIImageView
имеет размер (0, 0)
.
Как заставить этот эффект работать на iOS, со значением c Source
?
ПРИМЕЧАНИЕ. Эквивалентный Android эффект работает через обработчик, прикрепленный к ImageView.ViewTreeObserver.PreDraw
- когда размер известен. Так что, если существует iOS эквивалентное событие, это будет один из способов решения.
Подробнее:
В исходной реализации использовалось исходное изображение size (imageView.Image.Size) - который доступен во время OnAttach
. Это может быть сделано для «работы», но не является удовлетворительным: свечение применяется к полноразмерному изображению. Если изображение значительно больше области обзора, свечение становится слишком маленьким в радиусе (iOS сжимает изображение + свечение при визуализации): оно не имеет желаемого вида.
ApplyGlow
имеет возможность применить оттенок цвета к изображению. Этот оттенок отличается от цвета свечения. Я упоминаю об этом, потому что он ограничивает возможные решения: AFAIK, не может просто установить параметры для изображения и позволить iOS выяснить, как его визуализировать - необходимо явно изменить размер изображения и нарисовать измененное тонированное изображение поверх размытого изображения версия (свечение). Этот код все работает - , если imageView.Bounds.Size
(или imageView.Frame.Size
) доступен (и ненулевой).
С точкой останова в OnElementPropertyChanged
, Я проверил, известен ли размер imageView для любого свойства, которое всегда установлено. Нет; если динамически не установлены никакие свойства, все изменения свойств происходят до того, как imageView имеет размер.