如何在 Xamarin IOS 自定义渲染器中单击 UITextField Rightview 打开 UIPickerView

How to open a UIPickerView on click of UITextField's Rightview in Xamrin IOS customrenderer

我在 Xamarin ios 中使用 UITextFied 创建了一个自定义选择器,右侧带有向下箭头图像。当我单击向下箭头时,选择器没有打开。但是当 UITextField 的点击中心时,选择器正在打开。点击向下箭头时如何打开pickerview?

[assembly: ExportRenderer(typeof(CustomMonthPicker), typeof(CustomMonthPickerRenderer))]
namespace AMS.iOS.CustomRenderer
{
    public class CustomMonthPickerRenderer : ViewRenderer<CustomMonthPicker, UITextField>
    {
        private DateTime _selectedDate;
        private UITextField _dateLabel;
        private PickerDateModel _pickerModel; 

        protected override void OnElementChanged(ElementChangedEventArgs<CustomMonthPicker> e)
        {
            try
            {
                base.OnElementChanged(e);
                _dateLabel = new UITextField();

                var dateToday = Element.Date;
                SetupPicker(new DateTime(dateToday.Year, dateToday.Month, 1));

                SetNativeControl(_dateLabel);

                Control.EditingChanged += ControlOnEditingChanged;
                Element.PropertyChanged += Element_PropertyChanged;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
 
        private void ControlOnEditingChanged(object sender, EventArgs e)
        {
            if (Element.Date.ToString().Equals(DateTime.MinValue.ToString()))
            {
                _dateLabel.Text = "";
            }
            else
            {
                var monthName = SetMonthNumberToMonthName(Element.Date.Month);
                var currentDate = $"{monthName} | {Element.Date.Year}";

                if (_dateLabel.Text != currentDate)
                {
                    _dateLabel.Text = currentDate;
                }
            }
        }

        protected override void Dispose(bool disposing)
        {
            Element.PropertyChanged -= Element_PropertyChanged;
            base.Dispose(disposing);
        }

        private void SetupPicker(DateTime date)
        {
            var datePicker = new UIPickerView();

            _pickerModel = new PickerDateModel(datePicker, date);
            datePicker.ShowSelectionIndicator = true;

            _selectedDate = date;
            _pickerModel.PickerChanged += (sender, e) =>
            {
                _selectedDate = e;
            };
            datePicker.Model = _pickerModel;
            //_pickerModel.MaxDate = Element.MaxDate ?? DateTime.MaxValue;
            //_pickerModel.MinDate = Element.MinDate ?? DateTime.MinValue;

            var toolbar = new UIToolbar
            {
                BarStyle = UIBarStyle.Default,
                Translucent = true
            };
            toolbar.SizeToFit();

            var doneButton = new UIBarButtonItem("Done", UIBarButtonItemStyle.Done,
                (s, e) =>
                {
                    Element.Date = _selectedDate;
                    if (_selectedDate == DateTime.MinValue)
                    {
                        Element.Date = DateTime.Now;
                    }
                    var monthNameText = SetMonthNumberToMonthName(Element.Date.Month);
                    _dateLabel.Text = $"{monthNameText} | {Element.Date.Year}";
                    MessagingCenter.Send<App>((App)Xamarin.Forms.Application.Current, "PreferredDateChanged");

                    _dateLabel.ResignFirstResponder();
                });

            toolbar.SetItems(new[] { new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace), doneButton }, true);
           
            Element.Date = _selectedDate;
            var monthName = SetMonthNumberToMonthName(Element.Date.Month);

            //if (Element.Date.Equals(DateTime.MinValue.ToString()))
            //{
            //    _dateLabel.Text = "";
            //}
            //else
            if (Element.Date.Year == 1)
            {
                _dateLabel.Text = "";
            }
            else
                _dateLabel.Text = $"{monthName} | {Element.Date.Year}";
            _dateLabel.InputAccessoryView = toolbar;
            _dateLabel.TextColor = Element.TextColor.ToUIColor();
            _dateLabel.VerticalAlignment = UIControlContentVerticalAlignment.Fill;

            _dateLabel.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
            _dateLabel.TextAlignment = (UITextAlignment)TextAlignment.Center;

            var downarrow = UIImage.FromBundle("brandIcon.png");
            CGSize iconSize = downarrow.Size;
            if (20 > -1)
                iconSize = new CGSize((float)20, (float)20);

            UIView paddingView = new UIView(new CGRect(0, 0, iconSize.Width + 8, iconSize.Height + 8));
            UIImageView sideView = new UIImageView(new CGRect(0, 4, iconSize.Width, iconSize.Height));
            sideView.Image = downarrow;
            paddingView.AddSubview(sideView);
            paddingView.UserInteractionEnabled = true;
            _dateLabel.RightViewMode = UITextFieldViewMode.Always;
            _dateLabel.RightView = paddingView;
            //var gesture = new UITapGestureRecognizer(()=> {
            //    if (datePicker != null)
            //    {
            //        //datePicker.Hidden = !datePicker.Hidden;
            //        _dateLabel.InputView.Hidden = !_dateLabel.InputView.Hidden;
            //        //_dateLabel.AccessibilityRespondsToUserInteraction = true;
            //    }
            //});
            //paddingView.AddGestureRecognizer(gesture);
            _dateLabel.RightView.UserInteractionEnabled = true;
           // _dateLabel.RightView.AddGestureRecognizer(gesture);
            _dateLabel.InputView = datePicker;
        }

        private void Element_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            try
            {
                if (e.PropertyName == CustomMonthPicker.MaxDateProperty.PropertyName)
                {
                    _pickerModel.MaxDate = Element.MaxDate ?? DateTime.MinValue;
                }
                else if (e.PropertyName == CustomMonthPicker.MinDateProperty.PropertyName)
                {
                    _pickerModel.MinDate = Element.MinDate ?? DateTime.MaxValue;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

如何在单击向下箭头时打开选择器视图?

正如 ToolmakerSteve 提到的,我们可以在图标上添加点击手势来聚焦文本文件,它会自动打开选择器视图。

试试下面的代码


UIView paddingView = new UIView(new CGRect(0, 0, iconSize.Width + 8, iconSize.Height + 8));
UIImageView sideView = new UIImageView(new CGRect(0, 4, iconSize.Width, iconSize.Height));
sideView.Image = downarrow;
paddingView.AddSubview(sideView);
paddingView.UserInteractionEnabled = true;
_dateLabel.RightViewMode = UITextFieldViewMode.Always;
_dateLabel.RightView = paddingView;

                
//add this 
sideView.UserInteractionEnabled = true;
UITapGestureRecognizer tap = new UITapGestureRecognizer(()=> {
    _dateLabel.BecomeFirstResponder();
});
paddingView.AddGestureRecognizer(tap);