ContentView 的自定义渲染器 (iOS)

Flo*_*ian 3 background ios xamarin xamarin.forms

我有以下几点

public class ViewBase : ContentView
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

当我在 XAML 中使用它时

<local:ViewBase xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:MyForms;"
    x:Class="MyForms.Finder" 
    BackgroundColor="Color.Yellow">

    <!-- ... -->

</local:ViewBase>
Run Code Online (Sandbox Code Playgroud)

当我为此使用 CustomRenderer 并且甚至(如下所示)在其中什么都不做时,上面的 BackgroundColor 没有设置。当我没有定义以下几行时,背景是预期的黄色。

[assembly: ExportRenderer(typeof(ViewBase), typeof(ViewRendererBase))]
namespace MyiOS
{    
    public class ViewRendererBase : ViewRenderer
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

BackgroundColor 是 ViewRenderer 的一个属性。我查看了代码,似乎 Control 没有设置(我不调用 SetNativeControl)它不能将 Control.BackgroundColor 设置为一个值。但为什么会发生这种情况?我的猜测是 ViewRenderer 的继承有问题,因为默认行为在 ContentView 上使用了不同的东西!?

jgo*_*SFT 5

不确定这是我们文档 [1] 中的错误还是ViewRendererSetBackgroundColor方法的 iOS代码 [2] 中的错误。所以有几种方法可以解决这个问题。一种是让您的自定义渲染器继承VisualElementRenderer<T>,例如:

public class ViewBaseRenderer : VisualElementRenderer<ContentView>
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

在 iOS 代码中检查默认渲染器类型时:

var contentRenderer = Platform.CreateRenderer(new ContentView())
var rendererType = contentRenderer.GetType();
Run Code Online (Sandbox Code Playgroud)

rendererType是 a VisualElementRenderer<T>,因此这似乎是 Forms 使用的默认渲染器,因此它似乎是文档中的错误。

另一个“解决方法”是使用ViewRenderer但覆盖该SetBackgroundColor方法:

public class ViewBaseRenderer : ViewRenderer
{
    protected override void SetBackgroundColor(Color color)
    {
        base.SetBackgroundColor(color);

        if (NativeView == null)
            return;

        if (color != Color.Default)
            NativeView.BackgroundColor = color.ToUIColor();
    }
Run Code Online (Sandbox Code Playgroud)

我已经向 Xamarin Forms 团队提出了这个问题,以确定它是文档中的错误还是ViewRenderer. 如果您查看我链接的表单源代码 [2],您会看到 ifControl为 null,在这种情况下,背景颜色从未设置。通过覆盖和添加代码来设置背景颜色,NativeView然后您可以解决这个可能的错误。

显然,文档似乎有误。如果你使用ViewRenderer你必须Control自己设置。其他渲染器继承ViewRenderer,比如LabelRender,设置Control了,但ViewRenderer没有,所以你要调用SetNativeControl()OnElementChanged覆盖,以创建和设置本机控制。请参阅此论坛帖子 [3]。就个人而言,我认为应该从默认使用的渲染器继承,在这种情况下是一个VisualElementRenderer<T>

[1] https://developer.xamarin.com/guides/xamarin-forms/custom-renderer/renderers/#Layouts

[2] https://github.com/xamarin/Xamarin.Forms/blob/74cb5c4a97dcb123eb471f6b1dffa1267d0305aa/Xamarin.Forms.Platform.iOS/ViewRenderer.cs#L99

[3] https://forums.xamarin.com/discussion/comment/180839#Comment_180839