如何在 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);
我在 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);