首页 > 解决方案 > Xamarin FOrms iOS:ImageRenderer CreateNativeControl 错误

问题描述

我正在尝试在 iOS 中实现自定义 ImageRenderer,将原生 UIImageView 子类化,但我在使用 CreateNativeControl 时遇到了一些问题。

在较旧的 Xamarin.Forms 版本(如 4.2)中,我初始化的自定义本机类protected override UIImageView CreateNativeControl() { return new NativeImage(); }看起来从未被调用(未显示我在构造函数中登录的消息)。自定义渲染器已正确初始化(记录了正确的消息)。

在最新的稳定版本(如 4.4)中,在覆盖 CreateNativeControl 时,据说返回类型必须是 FormsUIImageView,从来没有听说过,反正我也尝试子类化,但是和以前一样的问题,似乎它永远不会被调用因为没有记录构造函数消息。自定义渲染器已正确初始化(记录了正确的消息)。

这是我使用的代码:

public class IOSImageView : ImageRenderer
{
   public IOSImageView()
   {
   }

    protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
    {
        base.OnElementChanged(e);

        if(Control == null)
        {
            return;
        }

        Console.WriteLine("PIPPO created from Custom Renderer");  //this message is correctly logged
    }


    protected override UIImageView CreateNativeControl()  //FormsUIImageView  in XF 4.4
    {
        return new NativeImage();
    }

}

public class NativeImage : UIImageView  //FormsUIImageView in XF 4.4
{
    public NativeImage() : base()
    {
        Console.WriteLine("PIPPO created from native IOS");  //this message is NOT logged
    }

    public override void TouchesBegan(NSSet touches, UIEvent evt)
    {
        base.TouchesBegan(touches, evt);
        Console.WriteLine("PIPPO touched");  //this (of course because no NativeImage is shown and there is no image to touch) is NOT logged
    }
}

标签: c#iosxamarin.formsuiimageviewcustom-renderer

解决方案


FormsUIImageView 是 XF 4.4 之后的新功能,您可以查看 Xamarin.Forms发行说明

在您的情况下,您似乎想将 Image Renderer 设置为您的自定义 ImageView,对吗?

你应该调用SetNativeControl()

protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
   base.OnElementChanged(e);
   if(Control!=null)
   {
      SetNativeControl(new NativeImage());
   }
}

public class NativeImage : FormsUIImageView 
{
    public NativeImage() : base()
    {
         this.UserInteractionEnabled = true;
    }

    public override void TouchesBegan(NSSet touches, UIEvent evt)
    {
        base.TouchesBegan(touches, evt);
        Console.WriteLine("PIPPO touched");  //this (of course because no NativeImage is shown and there is no image to touch) is NOT logged
    }
}


推荐阅读