Xamarin 显示 iOS 来自 Image Tap 的 UIDatePicker

Xamarin Show iOS UIDatePicker from Image Tap

所以我正在使用 Xamarin 并尝试创建一个图像渲染器,当点击该渲染器时将显示 iOS 的 UIDatePicker。我的渲染器在 Android 上工作得很好,但我无法让日期选择器在 iOS 上显示。我的渲染器代码在下面,我对其进行了调试,然后一直通过 mTextField.BecomeFirstResponder();我 "thought" 将使日期选择器显示。

任何人都可以指出我正确的方向吗?我只需要那个选择器显示在屏幕上。一旦我可以显示它,我就可以随心所欲地处理它。

private void _DatePickerHasBeenTapped( object sender, EventArgs e )
    {
        if( mDatePickerDialog != null )
        {
            mDatePickerDialog.TouchCancel -= _DatePickerDialogOnCancelEvent;
            mDatePickerDialog.ValueChanged -= _DatePickerDialogOnValueChanged;
        }

        var date = mDatePicker.PickerDate == DateTime.MinValue
            ? DateTime.Today
            : mDatePicker.PickerDate;


        mTextField = new UITextField();

        mDatePickerDialog = new UIDatePicker { Mode = UIDatePickerMode.Date, TimeZone = new NSTimeZone( "UTC" ) };

        mDatePickerDialog.ValueChanged += _DatePickerDialogOnValueChanged;
        mDatePickerDialog.SetDate( date.ToNSDate(), false );

        var width = UIScreen.MainScreen.Bounds.Width;
        var toolbar = new UIToolbar( new RectangleF( 0, 0, (float)width, 44 ) ) { BarStyle = UIBarStyle.Default, Translucent = true };
        var spacer = new UIBarButtonItem( UIBarButtonSystemItem.FlexibleSpace );
        var doneButton = new UIBarButtonItem( UIBarButtonSystemItem.Done, ( o, a ) => mDatePickerDialog.ResignFirstResponder() );

        toolbar.SetItems( new[] { spacer, doneButton }, false );

        mTextField.InputView = mDatePickerDialog;
        mTextField.InputAccessoryView = toolbar;

        if( mTextField.CanBecomeFirstResponder )
        {
            mTextField.BecomeFirstResponder();
        }
    }

如果 UITextField 确实显示了,您的方法就会起作用。现在,您可以通过将 UITextField 添加到 VC 视图层次结构来 破解 它,但用负 cgrect 抵消它以使其离开屏幕并在 [=14= 之后将其删除] 处理程序:

var mTextField = new UITextView(new CGRect(-1000, -1000, 10, 10));
yourViewController.Add(mTextField);

注意:我已经看到屏幕外控件的响应器失败并在我需要它们作为虚假响应器时避免它们,但我知道其他人这样做......用户当心......:-/

或:

您可以通过编程方式或从包含选择器和 关闭 按钮的故事板设计 UIViewController,并在用户点击您的图像时显示它。点击关闭按钮,关闭控制器并将您的选择器日期发送到某处...

或:

对于这样的事情,我通常使用弹出式视图控制器。

示例:

var parentVC = this; // This would the "main" Form's ViewController, obtain it within your renderer

PopoverDelegate popoverDelegate = null;
var datePicker = new UIDatePicker(new CGRect(0, 0, parentVC.View.Frame.Width, 300));
popoverDelegate = new PopoverDelegate(datePicker, (date) =>
{
    // Post the date change back to Forms via an event, etc... 
    Console.WriteLine($"Date Choosen: {date}");
    datePicker.Dispose();
    popoverDelegate.Dispose();
});
using (var popOverStyleVC = new UIViewController
{
    ModalPresentationStyle = UIModalPresentationStyle.Popover
})
{
    var pc = popOverStyleVC.PopoverPresentationController;
    {
        pc.Delegate = popoverDelegate;
        pc.SourceView = parentVC.View;
        pc.SourceRect = imageButton.Frame; // a CGRect where you want the popup arrow to point
    }
    popOverStyleVC.PreferredContentSize = datePicker.Frame.Size;
    popOverStyleVC.View.Add(datePicker);
    parentVC.PresentViewController(popOverStyleVC, true, null);
}

结果:

上面缺失的部分UIPopoverPresentationControllerDelegate因为你到returnUIModalPresentationStyle.None 通过 UIModalPresentationStyle GetAdaptivePresentationStyle 其他弹出窗口未正确显示,这也是我发现解雇并提供日期回调的地方。

UIPopoverPresentationControllerDelegate:

public class PopoverDelegate : UIPopoverPresentationControllerDelegate
{
    public delegate void DatePicked(NSDate date);
    UIDatePicker datePicker;
    DatePicked datePicked;

    public PopoverDelegate(UIDatePicker datePicker, DatePicked datePicked)
    {
        this.datePicked = datePicked;
        this.datePicker = datePicker;
    }

    public override UIModalPresentationStyle GetAdaptivePresentationStyle(UIPresentationController forPresentationController)
    {
        return UIModalPresentationStyle.None;
    }

    public override void DidDismissPopover(UIPopoverPresentationController popoverPresentationController)
    {
        datePicked(datePicker.Date);
    }
}