在 Xamarin Forms for iOS 上向编辑器底部添加边框

2024-03-24

目前,我的 Xamarin 表单应用程序中有输入字段,这些输入字段在 iOS 上只有底部边框,可以使用以下自定义渲染器完美运行:

using Xamarin.Forms.Platform.iOS;
using Xamarin.Forms;
using UIKit;
using YOUTNAMESPACE.iOS;
using System.ComponentModel;
using CoreAnimation;
using Foundation;

[assembly: ExportRenderer (typeof(YOUTNAMESPACE.LineEntry), typeof(LineEntryRenderer))]
namespace YOUTNAMESPACE.iOS
{
    public class LineEntryRenderer: EntryRenderer
    {
        protected override void OnElementChanged (ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged (e);

            if (Control != null) {
                Control.BorderStyle = UITextBorderStyle.None;

                var view = (Element as LineEntry);
                if (view != null) {
                    DrawBorder (view);
                    SetFontSize (view);
                    SetPlaceholderTextColor (view);
                }
            }
        }

        protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged (sender, e);

            var view = (LineEntry)Element;

            if (e.PropertyName.Equals (view.BorderColor))
                DrawBorder (view);
            if (e.PropertyName.Equals (view.FontSize))
                SetFontSize (view);
            if (e.PropertyName.Equals (view.PlaceholderColor))
                SetPlaceholderTextColor (view);
        }

        void DrawBorder (LineEntry view)
        {
            var borderLayer = new CALayer ();
            borderLayer.MasksToBounds = true;
            borderLayer.Frame = new CoreGraphics.CGRect (0f, Frame.Height / 2, Frame.Width, 1f);
            borderLayer.BorderColor = view.BorderColor.ToCGColor ();
            borderLayer.BorderWidth = 1.0f;

            Control.Layer.AddSublayer (borderLayer);
            Control.BorderStyle = UITextBorderStyle.None;
        }

        void SetFontSize (LineEntry view)
        {
            if (view.FontSize != Font.Default.FontSize)
                Control.Font = UIFont.SystemFontOfSize ((System.nfloat)view.FontSize);
            else if (view.FontSize == Font.Default.FontSize)
                Control.Font = UIFont.SystemFontOfSize (17f);
        }

        void SetPlaceholderTextColor (LineEntry view)
        {
            if (string.IsNullOrEmpty (view.Placeholder) == false && view.PlaceholderColor != Color.Default) {
                var placeholderString = new NSAttributedString (view.Placeholder, 
                                            new UIStringAttributes { ForegroundColor = view.PlaceholderColor.ToUIColor () });
                Control.AttributedPlaceholder = placeholderString;
            }
        }
    }
}

然而,当我将相同的逻辑应用于编辑器(多行 UITextField)时,边框出现在它应该出现的位置,但是在输入多行时,边框会在编辑器中向上移动,并按顺序显示文本。我怎样才能避免这种情况,使底部边框保持在同一个地方?


Solution

在 Xamarin Forms Editor 的自定义渲染器中,您需要执行两件事:

  1. private CALayer borderLayer;
    int sublayerNumber = 0;
    protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
    {
        base.OnElementChanged(e);
    
        if (Control != null)
        {
            borderLayer = new CALayer();
            Control.Layer.AddSublayer(borderLayer);
            sublayerNumber = Control.Layer.Sublayers.Length - 1;
    

您必须将 borderLayer 设为全局变量,然后创建另一个名为 sublayerNumber 的全局变量,然后在 OnElementChanged 内部,检查控件是否存在后,实例化 CALayer,然后将空白图层添加到子图层并获取其在子图层数组中的索引。

2.

 public override void LayoutSubviews()
        {
            base.LayoutSubviews();
            Control.Layer.Sublayers[sublayerNumber].MasksToBounds = true;
            Control.Layer.Sublayers[sublayerNumber].Frame = new CoreGraphics.CGRect(0f, Frame.Height - 5, Frame.Width, 1f);
            Control.Layer.Sublayers[sublayerNumber].BorderColor = Color.FromHex("YOUR-HEX-CODE-HERE").ToCGColor();
            Control.Layer.Sublayers[sublayerNumber].BorderWidth = 1.0f;
        }

重写 LayoutSubviews 方法,然后使用最新的帧高度和宽度等编辑我们在 OnElementChanged 中创建的特定图层。

Reason

在我们添加子视图之前,在调用layoutsubviews方法之前,导致它显示不正确。

我们创建一个 CALayer,然后将其添加到子层,然后每次调用 LayoutSubviews 时对其进行编辑的原因是,如果您的编辑器(iOS 中的 UITextField)尺寸扩大或缩小,边框将跟随容器本身。如果用户添加了此附加功能以允许这样做,这一点很重要。

希望这对那些和我至少一天拔头发有同样问题的人有所帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Xamarin Forms for iOS 上向编辑器底部添加边框 的相关文章

随机推荐