【问题标题】:Xamarin Forms iOS renderer DimensionsXamarin Forms iOS 渲染器尺寸
【发布时间】:2017-10-07 03:28:12
【问题描述】:

我正在尝试为 iOS 创建一个“通用”渲染器,但无法确定渲染器的尺寸。

PCL 中的渲染器类非常简单,唯一的“特殊”是继承自 View,因为我想将它用作通用渲染器

public class ExampleView : View { }

在XAML中也很典型

<renderers:ExampleView />

iOS项目中渲染器的定义如下

public class ExampleRenderer : ViewRenderer<ExampleView, UIView>
{
    protected override void OnElementChanged(ElementChangedEventArgs<ExampleView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            SetNativeControl(new UIView(new CGRect(0, 0, 0, 300)));
        }
    }
}

这里有趣的部分是该类继承自ViewRenderer&lt;ExampleView, UIView&gt;

似乎虽然我指定渲染的宽度为 0,但实际渲染器占用了页面的整个宽度。

事实上,我设置的任何宽度值都将被忽略,渲染器将占据整个页面。

这还不错,是无意的,这让我感到困扰。 (或者我做错了什么?)

所以这里的问题是如何在我的自定义渲染中找到占用的宽度?

【问题讨论】:

    标签: xamarin.forms


    【解决方案1】:

    占用空间的不是渲染器,而是本机控件。渲染器正在完成它的工作,即保持本机控件与表单控件同步 - 其中包括 layout parse requests。

    为了控制大小限制,我建议在表单Element 上使用属性WidthRequest 或HeightRequest 来做到这一点。它会通过渲染器自动滴到原生Control.Frame。

    EDIT-1

    如果您想根据当前边界更新您的原生控件(或子视图),您可以使用OnElementPropertyChanged 来跟踪更改。可能导致尺寸更新的原因有很多 - 例如设备方向更改、父布局、第一次布局传递等。

    public class ExampleRenderer : ViewRenderer<ExampleView, UIView>
    {
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
    
            if (e.PropertyName == VisualElement.WidthProperty.PropertyName ||
                e.PropertyName == VisualElement.HeightProperty.PropertyName)
            {
                if(Element != null && Element.Bounds.Height > 0 && Element.Bounds.Width > 0)
                {
                    //update size on native control's subviews
                    // or use SetNeedsDisplay() to re-draw
                    //Note: force update to Control's size is not recommended (as it is recommended it be same as forms element)
                    //Instead add a subview that you can update for size here
                }   
            }
        }
    

    【讨论】:

    • 我在问问题之前尝试了WidthRequest 和HeightRequest,但它们没有任何区别。实际上,我分配给这些属性的数字不会出现在自定义渲染器中的任何位置。在我发布的代码中,本机控件还没有任何大小!那么,既然我不知道屏幕的大小也不知道如何获取,我怎么能从控件中要求占据屏幕大小的一半呢? e.NewElement.Bounds 的宽度和高度等于 -1。
    • WidthRequest 和 HeighRequest 在某些父布局中可以忽略。只有在表单元素的布局传递发生后,本机控件才会具有大小。为了能够跟踪元素边界 - 您需要使用 OnElementPropertyChanged(类似于 OnSizeAllocated)
    • 是的,它正在工作。似乎只有SetNativeControl(new UIView()); 就可以了。正如你所说,我可以在 XAML 中指定 HeightRequest。事件的顺序很重要。首先是OnElementChanged,然后是OnElementPropertyChanged 的多次传递,然后在if 语句中,SetNeedsDisplay(); 将触发Draw(CGRect rect),其中我有最终的rect 具有适当的值。我之前画的是错误的。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2015-06-18
    • 2016-09-03
    • 2018-07-23
    • 2018-04-12
    • 2017-10-09
    相关资源
    最近更新 更多