【问题标题】:Xamarin Show iOS UIDatePicker from Image TapXamarin 从 Image Tap 显示 iOS UIDatePicker
【发布时间】:2018-02-18 07:13:05
【问题描述】:

所以我正在使用 Xamarin 并尝试创建一个图像渲染器,当点击它时将显示 iOS 的 UIDatePicker。我的渲染器非常适合 Android,但我无法让日期选择器在 iOS 上显示。我的代码在渲染器下面,我对其进行了调试,我一直通过 mTextField.BecomeFirstResponder();我“认为”会让日期选择器显示出来。

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

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

【问题讨论】:

    标签: c# xamarin xamarin.ios uidatepicker


    【解决方案1】:

    如果UITextField 实际正在显示,您的方法将起作用。现在您可以破解它,方法是将 UITextField 添加到 VC 视图层次结构中,但使用负 cgrect 将其从屏幕上移开,然后在 UIBarButtonItem 处理程序中将其删除:

    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,因为您通过UIModalPresentationStyle GetAdaptivePresentationStyle返回UIModalPresentationStyle.None,其他弹出框未正确显示,这也是我在哪里赶上解雇并提供带有日期的回调。

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

    【讨论】:

    • 感谢您的信息。我会试试这个。在您回复的开头,我不明白您关于没有按钮供用户选择完成的评论。我正在创建一个带有完成按钮的工具栏,以便用户可以单击该按钮。我仍然对为什么我正在做的事情不起作用感到困惑。日期选择器对话框的构建与 Xamarin 表单日期选择器渲染器非常相似。我只是不知道为什么它不会显示。是因为我的 UITextField 不在屏幕上/可见吗?
    • @theDoke 错过了InputAccessoryView,需要更多的咖啡 ;-) 这会起作用,但你需要在 UITextField 上 ResignFirstResponder 而不是选择器,当然此时要捕获选择器日期。如果控件(基于图像的 uiview?)是视图层次结构上的输入控件,您将拥有什么,现在您可以通过将 UITextField 添加到 VC 视图但用负 cgrect 抵消它来破解它在 UIBarButtonItem 处理程序中将其移出屏幕并删除它。我倾向于避免那些屏幕外的 UIView,因为我看到它们随机失败......
    猜你喜欢
    • 2021-04-19
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    相关资源
    最近更新 更多