在 Xamarin Forms for iOS 的底部和编辑器添加边框 [英] Adding a border to the bottom of and Editor on Xamarin Forms for iOS

查看:24
本文介绍了在 Xamarin Forms for iOS 的底部和编辑器添加边框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I Currently have entry fields in my Xamarin forms app that just have bottom borders on iOS that work perfectly using the following custom renderer:

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)时,边框会出现在它应该出现的位置,但是在键入多行时,边框会随着按下顺序的文本向上移动到编辑器.我怎样才能避免这种情况,以便底部边框只是停留在同一个地方?

However when I apply the same logic to an Editor (a multiline UITextField) the border appears where it should, however on typing multiple lines, the border moves up the editor with the text on pressing order. How can I avoid this so that the bottom border simply stays in the same place?

推荐答案

解决方案

在 Xamarin 表单编辑器的自定义渲染器中,您需要做两件事:

In your custom renderer for a Xamarin Forms Editor, you need to do two things:

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设为全局变量,然后在OnElementChanged内部创建另一个名为sublayerNumber的全局变量,检查控件是否存在后,实例化CALayer,然后将空白图层添加到子图层中,并在子图层数组中获取其索引.

You must make the borderLayer global, then make another global variable called sublayerNumber and then inside of OnElementChanged, after checking if the control exists, instantiate the CALayer and then add the blank layer to the sublayers and get its index in the sublayers array.

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 中创建的特定图层.

Override the method LayoutSubviews and then edit the specific layer that we created in OnElementChanged with the most recent frame height and width etc.

原因

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

Before we were adding the subview before the layoutsubviews method was called causing it to be displayed incorrectly.

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

The reason we create one CALayer and then add it to the sublayers and then edit it every time LayoutSubviews is called is so that if your Editor (UITextField in iOS) expands in size or contracts in size the border will follow the container itself. This is important if the user has added this additional functionality to allow this.

希望这能帮助那些与我至少拉了一天头发有同样问题的人!

这篇关于在 Xamarin Forms for iOS 的底部和编辑器添加边框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆