ios - 效果如何找出它所附加的 UIImageView 的显示大小?

标签 ios xamarin.forms uiimageview

在 Xamarin.Forms 中,一个 Effect可以附加到 View。在我的例子中, 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 (BoundsFrame) 有一个尺寸。但是,如果在 XAML 中静态设置源,则该逻辑不会运行:因此对 ApplyGlow 的唯一调用是在 OnAttach 期间。不幸的是,在 OnAttach 期间,UIImageView 的大小为 (0, 0)

如何使用静态 Source 在 iOS 上实现这种效果?

注意:等效的 Android 效果通过附加到 ImageView.ViewTreeObserver.PreDraw 的处理程序工作 - 此时大小已知。因此,如果有 iOS 等效事件,那将是一种解决方法。


更多详情:

  • 原始实现使用原始图像大小 (imageView.Image.Size) - 这在 OnAttach 期间可用。这可以“工作”,但并不令人满意:发光应用于全尺寸图像。如果图像明显大于 View 区域,发光的半径会变得太小(iOS 在渲染时缩小图像 + 发光):它没有所需的外观。

  • ApplyGlow 有一个选项可以将色调颜色应用到图像。该色调颜色不同于发光颜色。我提到这个是因为它限制了可能的解决方案:AFAIK,不能只在图像上设置选项并让 iOS 弄清楚如何渲染它 - 需要明确调整图像大小并在模糊版本的顶部绘制调整大小的着色图像(光辉)。此代码全部有效 - if imageView.Bounds.Size(或 imageView.Frame.Size)可用(且非零)。

  • 通过 OnElementPropertyChanged 中的断点,我检查了 imageView 大小是否已知任何始终设置的属性。不;如果没有动态设置属性,则属性更改全部发生在 imageView 具有大小之前。

最佳答案

也许这是一种解决方法,我不知道您是否可以接受。

OnAttached 中调用 ApplyGlow(); 之前添加一点延迟。延迟后,您将获得 imageView.Frame.SizeimageView.Bounds.Size

protected override async void OnAttached()
{
    await Task.Delay(TimeSpan.FromSeconds(0.3));// it can be 0.2s,0.1s, depending on you
    ApplyGlow();
}

如果你设置了WidthRequest, HeightRequest,你可以毫不拖延地到达那里:

private void ApplyGlow()
{
    var imageView = Control as UIImageView;
    if (imageView.Image == null)
        return;

    Console.WriteLine(imageView.Image.Size.Width);
    Console.WriteLine(imageView.Image.Size.Height);

    CoreGraphics.CGSize rect = imageView.Bounds.Size;
    CoreGraphics.CGSize rect2 = imageView.Frame.Size;

    Console.WriteLine(rect);
    Console.WriteLine(rect2);

    double width = (double)Element.GetValue(VisualElement.WidthRequestProperty);
    double height = (double)Element.GetValue(VisualElement.HeightRequestProperty);

    Console.WriteLine(width);
    Console.WriteLine(height);

    double width2 = (double)Element.GetValue(VisualElement.WidthProperty);
    double height2 = (double)Element.GetValue(VisualElement.HeightProperty);

    Console.WriteLine(width2);
    Console.WriteLine(height2);
}

关于ios - 效果如何找出它所附加的 UIImageView 的显示大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59759475/

相关文章:

ios - 在 OpenGL ES 2.0 GLSL 中转置 mat4

c# - Xamarin Forms - 仅在图像而不是整个屏幕上使用捏合手势

xamarin.forms - 如何为手机和平板电脑开发 Xamarin 表单应用程序

xamarin - 为什么需要在 Xamarin.Forms 应用中更改程序集名称?

swift - 将图像发送到新的 View Controller

ios - pageControl 中的 ScrollView 延迟/滞后

objective-c - 如何让 imageview 做一个 segue

ios - 在 TableView 中返回多个 dequeueReusableCells,Swift

android - 在移动应用程序(iOS/Android)上显示我的栅格 map

IOS同步技术