1

I have a created a custom Picker with downarrow image at right side using UITextFied in Xamarin ios. When I click the downarrow, the picker is not opening. But when the click centre of the UITextField, the picker is opening. How to open the pickerview when click of downarrow?

[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);
            }
        }
    }
}

How to open the pickerview when click of downarrow?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Devanathan
  • 39
  • 5
  • I didn't read code carefully, but my first guess is that the downarrow has its own click property, so you need to add code on its click event also. Maybe someone else will come along and can explain in more detail... – ToolmakerSteve Jul 06 '21 at 09:14

1 Answers1

0

As ToolmakerSteve mentioned , we can add a tap gesture on the icon to focus the textfiled and it will open picker view automacially .

Try the following code


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);

ColeX
  • 14,062
  • 5
  • 43
  • 240