Open divyesh008 opened 1 year ago
Is there any specific reason you're not using the handlers/mappers? Also you mention version 6.0.312, is that correct? Does it work when you update to the latest version (.NET 7)?
Hi @divyesh008. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
@jfversluis It's just because I want to utilize what I already have. We can use Renderers still in MAUI (https://github.com/dotnet/maui/wiki/Using-Custom-Renderers-in-.NET-MAUI), right?
Tbh I have tried to convert it to a handler but did not get an idea of how to do that for this requirement. From the document, I was not getting a clear idea.
And yes with .Net 7 also it's not working.
@jfversluis I have used handlers/mappers now.
public class NullableDatePickerRenderer : DatePickerHandler
{
protected override MauiDatePicker CreatePlatformView()
{
return base.CreatePlatformView();
}
protected override void ConnectHandler(MauiDatePicker platformView)
{
var datePicker = VirtualView as NullableDatePicker;
var platformPicker = new MauiDatePicker();
var originalToolbar = platformPicker.InputAccessoryView as UIToolbar;
if (originalToolbar != null && originalToolbar.Items.Length <= 2)
{
var clearButton = new UIBarButtonItem("Clear", UIBarButtonItemStyle.Plain, ((sender, ev) =>
{
datePicker.Unfocus();
datePicker.Date = DateTime.Now;
datePicker.CleanDate();
}));
var newItems = new List<UIBarButtonItem>();
foreach (var item in originalToolbar.Items)
{
newItems.Add(item);
}
newItems.Insert(0, clearButton);
originalToolbar.Items = newItems.ToArray();
originalToolbar.SetNeedsDisplay();
platformView.InputAccessoryView = originalToolbar;
platformView.ReloadInputViews();
base.ConnectHandler(platformView);
}
}
}
With this, I have got the Clear button with the working condition but now the Done button has stopped working. On the Click of Done button, it should close the picker but that has stopped now.
In regard to the custom renderer, looking at your code it seems that you have missed this step to actually register the renderer: https://github.com/dotnet/maui/wiki/Using-Custom-Renderers-in-.NET-MAUI#configure-renderers
For the new approach, I'm not exactly sure what you're trying to do, this might help to get you started with customizing controls: https://learn.microsoft.com/dotnet/maui/user-interface/handlers/customize?view=net-maui-7.0
Can you confirm that, if you still want to use the custom renderer, it works when you actually register it? Customizing through handlers and mappers does work, implementing the right code for what you want to do is a bit beyond the scope of issues. For more "how to" like questions I would like to refer you to the Discussions or forums like Stack Overflow or Reddit.
Hi @divyesh008. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
https://github.com/dotnet/maui/wiki/Using-Custom-Renderers-in-.NET-MAUI#configure-renderers
✅ Does work fine on Android ❌ Does not work on iOS
@jfversluis I have used handlers/mappers now.
public class NullableDatePickerRenderer : DatePickerHandler { protected override MauiDatePicker CreatePlatformView() { return base.CreatePlatformView(); } protected override void ConnectHandler(MauiDatePicker platformView) { var datePicker = VirtualView as NullableDatePicker; var platformPicker = new MauiDatePicker(); var originalToolbar = platformPicker.InputAccessoryView as UIToolbar; if (originalToolbar != null && originalToolbar.Items.Length <= 2) { var clearButton = new UIBarButtonItem("Clear", UIBarButtonItemStyle.Plain, ((sender, ev) => { datePicker.Unfocus(); datePicker.Date = DateTime.Now; datePicker.CleanDate(); })); var newItems = new List<UIBarButtonItem>(); foreach (var item in originalToolbar.Items) { newItems.Add(item); } newItems.Insert(0, clearButton); originalToolbar.Items = newItems.ToArray(); originalToolbar.SetNeedsDisplay(); platformView.InputAccessoryView = originalToolbar; platformView.ReloadInputViews(); base.ConnectHandler(platformView); } } }
With this, I have got the Clear button with the working condition but now the Done button has stopped working. On the Click of Done button, it should close the picker but that has stopped now.
@divyesh008 can you rework the description of this issue or open a new issue with regards to what you are hitting with the handler?
My guess with your initial issue is that you weren't calling "SetNativeControl" the ViewRenderer
and VisualElementRenderer
classes don't automatically create the platform control for you
Hi @divyesh008. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.
@PureWeen I have just tried with Handler. The original issue is Renderer is not working in iOS. And in iOS SetNativeControl was not required it was for Android, and in Android, it does work fine.
The issue is with iOS that => this.Control gives null in iOS renderer.
@PureWeen I have just tried with Handler. The original issue is Renderer is not working in iOS. And in iOS SetNativeControl was not required it was for Android, and in Android, it does work fine.
The issue is with iOS that => this.Control gives null in iOS renderer.
Any updates?
@jfversluis I have used handlers/mappers now. With this, I have got the Clear button with the working condition but now the Done button has stopped working. On the Click of Done button, it should close the picker but that has stopped now.
You can use something like this to fix done button, but the issue with this.Control is still(:
var setButton = new UIBarButtonItem("Done", UIBarButtonItemStyle.Done, ((sender, ev) =>
{
datePicker.Unfocus();
datePicker.Format = datePicker._originalFormat;
}));
var newItems = new List<UIBarButtonItem>();
newItems.Add(clearButton);
newItems.Add(originalToolbar.Items[0]);
newItems.Add(setButton);
originalToolbar.Items = newItems.ToArray();
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
Verified this issue with Visual Studio Enterprise 17.7.0 Preview 2.0. Can repro on iOS platform with sample project. CustomRenderers_MAUI-main.zip
@jfversluis
I'm also facing issue with Custom Renderer and Handler.
I've tried reusing the custom renderer after upgrading to MAUI. It works fine in sample MAUI project. But not working when integrated in main project. Both the files have same code and also I've verified the registration of renderer in MauiProgram.
I later created Handler. Again it works fine in sample MAUI project. But not working when integrated in main project. Both the files have same code and also I've verified the registration of Handler in MauiProgram.
The repo of the sample project can be found with the following link: https://github.com/apy534/MAUI-Handler-test
OK folks I realise this is a bit off-topic. But for anyone trying to implement a 'nullable' / clearable date field, that works on iOS, here's a solution I've got. It builds on what others have done here using the 'Handler' approach:
(in this implementation the date is updated when the 'done' button is pressed, rather than it doing nothing as above)
public class DateFieldRenderer : DatePickerHandler
{
protected override MauiDatePicker CreatePlatformView()
{
return base.CreatePlatformView();
}
protected override void ConnectHandler(MauiDatePicker platformView)
{
var datePicker = VirtualView as DateField;
var platformPicker = new MauiDatePicker();
var originalToolbar = platformPicker.InputAccessoryView as UIToolbar;
if (originalToolbar != null && originalToolbar.Items.Length <= 2)
{
var clearButton = new UIBarButtonItem("Clear", UIBarButtonItemStyle.Plain, ((sender, ev) =>
{
datePicker.Date = DateTime.Now;
datePicker.CleanDate();
platformView.ResignFirstResponder();
}));
var setButton = new UIBarButtonItem("Done", UIBarButtonItemStyle.Done, ((sender, ev) =>
{
var inputView = platformView.InputView as UIDatePicker;
datePicker.Date = (DateTime) inputView.Date;
platformView.ResignFirstResponder();
}));
var newItems = new List<UIBarButtonItem>();
newItems.Add(clearButton);
newItems.Add(originalToolbar.Items[0]);
newItems.Add(setButton);
originalToolbar.Items = newItems.ToArray();
originalToolbar.SetNeedsDisplay();
platformView.InputAccessoryView = originalToolbar;
platformView.ReloadInputViews();
}
}
}
If you want the default (null) date not to display the current date then you will also need the following in your MauiProgram class:
in the CreateMauiApp() method under the builder:
.ConfigureMauiHandlers((handlers) =>
{
#if ANDROID
handlers.AddHandler(typeof(DateField), typeof(mobile.Droid.DateFieldRenderer));
#elif IOS
handlers.AddHandler(typeof(DateField), typeof(mobile.iOS.DateFieldRenderer));
#endif
Microsoft.Maui.Handlers.DatePickerHandler.Mapper.AppendToMapping("NullableDateField", (handler, view) =>
{
if (view is DateField picker)
{
#if IOS
SetNullableText((DateField)view, handler.PlatformView);
#endif
}
});
});
private static void SetNullableText(DateField view, MauiDatePicker platformDatePicker)
{
if (view.NullableDate == null)
platformDatePicker.Text = string.Empty;
else
platformDatePicker.Text = view.Date.ToString("dd/MM/yyyy"); // Be careful - UK date format hard coded here it should probably use the format set on the date field instead
}
Hope this helps someone... seems like a pretty common use case for a date field - perhaps it could be implemented in the core of MAUI some day?
Description
I want to create a CustomDatePicker that supports nullable date and also provides a Clear action button. So that if users want to clear the selection they can. I have done R&D and found that we can use Xamarin.Forms renderers in .net Maui from here: https://github.com/dotnet/maui/wiki/Using-Custom-Renderers-in-.NET-MAUI
For the same requirements, I have got a solution and sample project posted by Charlin Agramonte (below link): https://xamgirl.com/clearable-datepicker-in-xamarin-forms/
Implemented same logic in .Net MAUI project. It does work fine in Android but in iOS custom renderer this.Control gives null.
Steps to Reproduce
Link to public reproduction project repository
https://github.com/divyesh008/CustomRenderers_MAUI
Version with bug
6.0.312
Last version that worked well
6.0.312
Affected platforms
iOS
Affected platform versions
iOS 15
Did you find any workaround?
No
Relevant log output
No response