Skip to main content
 首页 » 编程设计

c#之Xamarin 从 Image Tap 显示 iOS UIDatePicker

2024年02月04日63xiaohuochai

所以我正在使用 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(); 
        } 
    } 

请您参考如下方法:

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

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

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

或者:

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

或者:

对于这样的事情,我通常使用弹出式样式的 View Controller 。

示例:

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