Xamarin 从 Image Tap 显示 iOS UIDatePicker

Posted

技术标签:

【中文标题】Xamarin 从 Image Tap 显示 iOS UIDatePicker【英文标题】:Xamarin Show iOS UIDatePicker from Image Tap 【发布时间】: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();
        
    

【问题讨论】:

【参考方案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,因为我看到它们随机失败......

以上是关于Xamarin 从 Image Tap 显示 iOS UIDatePicker的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin 表单自定义 GridView Tap 和 Long Tap 不能一起工作

Xamarin.Forms Tap Gesturer 没有响应

如何在 Xamarin.Forms 中使用 Tap Gesture 调用另一个页面?

DisplayAlert不在Xamarin上显示仅表示ios

DisplayAlert 仅在 Xamarin 表单 ios 上不显示

Xamarin.iOS 无法在推送通知中显示照片