Добавление границы в нижней части и редактора в Xamarin Forms для iOS - PullRequest
0 голосов
/ 25 июня 2018

У меня в настоящее время есть поля ввода в моем приложении форм 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;
            }
        }
    }
}

Однако, когда я применяю ту же логику к редактору (multiline UITextField) граница появляется там, где и должна, однако при наборе нескольких строк она перемещается вверх по редактору с текстом в порядке нажатия.Как я могу избежать этого, чтобы нижняя граница просто оставалась на том же месте?

1 Ответ

0 голосов
/ 30 июня 2018

Решение

В пользовательском рендерере для редактора форм Xamarin вам нужно сделать две вещи:

  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, с использованием самой последней высоты и ширины кадра и т. Д.

Причина

Прежде чем мы добавили подпредставление до вызова метода layoutsubviews, из-за чего оно отображалось некорректно.

Причина, по которой мы создаем один CALayer, а затем добавляем его в подслои и затем редактируем его при каждом вызове LayoutSubviews, заключаются в том, что если ваш редактор (UITextField в iOS) расширяется в размере или сокращается в размере, граница будет следовать за самим контейнером , Это важно, если пользователь добавил эту дополнительную функциональность, чтобы разрешить это.

Надеюсь, что это поможет любому, у кого была такая же проблема, как и то, что я вырывал свои волосы хотя бы один день!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...