Existe una solución sencilla para esto. Al usar DependencyService , puede obtener fácilmente el enfoque Toast-Like tanto en Android como en iOS.
Cree una interfaz en su paquete común.
public interface IMessage
{
void LongAlert(string message);
void ShortAlert(string message);
}
Sección de Android
[assembly: Xamarin.Forms.Dependency(typeof(MessageAndroid))]
namespace Your.Namespace
{
public class MessageAndroid : IMessage
{
public void LongAlert(string message)
{
Toast.MakeText(Application.Context, message, ToastLength.Long).Show();
}
public void ShortAlert(string message)
{
Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
}
}
}
sección de iOS
En iOs no existe una solución nativa como Toast, por lo que debemos implementar nuestro propio enfoque.
[assembly: Xamarin.Forms.Dependency(typeof(MessageIOS))]
namespace Bahwan.iOS
{
public class MessageIOS : IMessage
{
const double LONG_DELAY = 3.5;
const double SHORT_DELAY = 2.0;
NSTimer alertDelay;
UIAlertController alert;
public void LongAlert(string message)
{
ShowAlert(message, LONG_DELAY);
}
public void ShortAlert(string message)
{
ShowAlert(message, SHORT_DELAY);
}
void ShowAlert(string message, double seconds)
{
alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
{
dismissMessage();
});
alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
}
void dismissMessage()
{
if (alert != null)
{
alert.DismissViewController(true, null);
}
if (alertDelay != null)
{
alertDelay.Dispose();
}
}
}
}
Tenga en cuenta que en cada plataforma, tenemos que registrar nuestras clases con DependencyService.
Ahora puede acceder al servicio Toast en cualquier lugar de nuestro proyecto.
DependencyService.Get<IMessage>().ShortAlert(string message);
DependencyService.Get<IMessage>().LongAlert(string message);
DismissMessage
.Aquí hay una versión del código iOS de Alex Chengalan que evita que la interfaz de usuario se quede pegada cuando se muestran varios mensajes ...
public class MessageIOS : IMessage { const double LONG_DELAY = 3.5; const double SHORT_DELAY = 0.75; public void LongAlert(string message) { ShowAlert(message, LONG_DELAY); } public void ShortAlert(string message) { ShowAlert(message, SHORT_DELAY); } void ShowAlert(string message, double seconds) { var alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert); var alertDelay = NSTimer.CreateScheduledTimer(seconds, obj => { DismissMessage(alert, obj); }); UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null); } void DismissMessage(UIAlertController alert, NSTimer alertDelay) { if (alert != null) { alert.DismissViewController(true, null); } if (alertDelay != null) { alertDelay.Dispose(); } } }
fuente
Puede usar el paquete Acr.UserDialogs de nuget y el código como se muestra a continuación,
Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));
fuente
Normalmente usamos el complemento Egors Toasts, pero como requiere permisos en iOS para un proyecto actual, hemos tomado una ruta diferente usando Rg.Plugins.Popup nuget ( https://github.com/rotorgames/Rg.Plugins.Popup ).
Escribí una página básica xaml / cs de tipo PopupPage,
<?xml version="1.0" encoding="utf-8" ?> <popup:PopupPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:popup="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup" x:Class="YourApp.Controls.ToastPage"> ...
y hacer que lo cree un servicio, cuya interfaz registre al iniciar la aplicación o use Xamarin.Forms.DependencyService para buscar el servicio también sería viable.
El servicio se actualiza en la página derivada de PopupPage y no
await PopupNavigation.PushAsync(newToastPage); await Task.Delay(2000); await PopupNavigation.PopAllAsync();
El usuario puede cerrar la página emergente tocando fuera de la pantalla de la página (suponiendo que no haya llenado la pantalla).
Esto parece funcionar felizmente en iOS / Droid, pero estoy abierto a la corrección si alguien sabe que es una forma arriesgada de hacerlo.
fuente
Agregando a la respuesta de Alex, aquí está la variante de UWP:
public class Message : IMessage { private const double LONG_DELAY = 3.5; private const double SHORT_DELAY = 2.0; public void LongAlert(string message) => ShowMessage(message, LONG_DELAY); public void ShortAlert(string message) => ShowMessage(message, SHORT_DELAY); private void ShowMessage(string message, double duration) { var label = new TextBlock { Text = message, Foreground = new SolidColorBrush(Windows.UI.Colors.White), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }; var style = new Style { TargetType = typeof(FlyoutPresenter) }; style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.Black))); style.Setters.Add(new Setter(FrameworkElement.MaxHeightProperty, 1)); var flyout = new Flyout { Content = label, Placement = FlyoutPlacementMode.Full, FlyoutPresenterStyle = style, }; flyout.ShowAt(Window.Current.Content as FrameworkElement); var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(duration) }; timer.Tick += (sender, e) => { timer.Stop(); flyout.Hide(); }; timer.Start(); } }
El color y el estilo dependen de usted, en
MaxHeight
realidad se requiere mantener la altura al mínimo.fuente
Puede usar IUserDialog NuGet y simplemente usar su toastAlert
var toastConfig = new ToastConfig("Toasting..."); toastConfig.SetDuration(3000); toastConfig.SetBackgroundColor(System.Drawing.Color.FromArgb(12, 131, 193)); UserDialogs.Instance.Toast(toastConfig);
fuente
Aquí hay un fragmento de código que estoy usando para mostrar el brindis en Xamarin.iOS
public void ShowToast(String message, UIView view) { UIView residualView = view.ViewWithTag(1989); if (residualView != null) residualView.RemoveFromSuperview(); var viewBack = new UIView(new CoreGraphics.CGRect(83, 0, 300, 100)); viewBack.BackgroundColor = UIColor.Black; viewBack.Tag = 1989; UILabel lblMsg = new UILabel(new CoreGraphics.CGRect(0, 20, 300, 60)); lblMsg.Lines = 2; lblMsg.Text = message; lblMsg.TextColor = UIColor.White; lblMsg.TextAlignment = UITextAlignment.Center; viewBack.Center = view.Center; viewBack.AddSubview(lblMsg); view.AddSubview(viewBack); roundtheCorner(viewBack); UIView.BeginAnimations("Toast"); UIView.SetAnimationDuration(3.0f); viewBack.Alpha = 0.0f; UIView.CommitAnimations(); }
fuente
Recomendaría la
Plugin.Toast
biblioteca denuget
. Funciona bien.CrossToastPopUp.Current.ShowToastMessage("my toast message");
o de ACR.UserDialogs Nuget libriary
UserDialogs.Instance.ShowLoading("Loading");
fuente
@MengTim, para solucionar el problema de las tostadas múltiples en la solución de @ alex-chengalan, simplemente envolví todo dentro
ShowAlert()
con una verificación para ver sialert
yalertDelay
son nulos, luego dentroDismissMessage
, anuladosalert
yalertDelay
.void ShowAlert(string message, double seconds) { if(alert == null && alertDelay == null) { alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) => { DismissMessage(); }); alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert); UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null); } } void DismissMessage() { if (alert != null) { alert.DismissViewController(true, null); alert = null; } if (alertDelay != null) { alertDelay.Dispose(); alertDelay = null; } }
Eso pareció al menos aclarar el bloqueo de la interfaz de usuario, si está buscando una solución rápida. Estaba tratando de mostrar el brindis en la navegación a una nueva página, y creo que la
PresentViewController
configuración estaba esencialmente cancelando mi navegación. Lo siento, no comenté en el hilo, mi reputación es demasiado baja :(fuente
No hay un mecanismo incorporado en Forms, pero este paquete nuget proporciona algo similar
https://github.com/EgorBo/Toasts.Forms.Plugin
Nota: Estos no son brindis al estilo de Android como se solicita en la pregunta, sino al estilo de UWP que son notificaciones de todo el sistema.
fuente
Esta es mi
ShowAlert
versión mejorada de la versión de Ian Warburton para garantizar que el brindis se muestre incluso en la página emergente. Además, el brindis se descarta si el usuario hace clic fuera del brindis. UséUIAlertControllerStyle.ActionSheet
ese look como tostadas pero también funciona conUIAlertControllerStyle.Alert
void ShowAlert(string message, double seconds) { var alert = UIAlertController.Create(null, message, UIAlertControllerStyle.ActionSheet); var alertDelay = NSTimer.CreateScheduledTimer(seconds, obj => { DismissMessage(alert, obj); }); var viewController = UIApplication.SharedApplication.KeyWindow.RootViewController; while (viewController.PresentedViewController != null) { viewController = viewController.PresentedViewController; } viewController.PresentViewController(alert, true, () => { UITapGestureRecognizer tapGesture = new UITapGestureRecognizer(_ => DismissMessage(alert, null)); alert.View.Superview?.Subviews[0].AddGestureRecognizer(tapGesture); }); }
Espero que esto ayude a alguien !
fuente
Yo uso https://github.com/ishrakland/Toast/ En https://www.nuget.org/packages/Plugin.Toast/
Ejemplo CrossToastPopUp.Current.ShowToastMessage ("Cargando", Plugin.Toast.Abstractions.ToastLength.Short);
Pruébalo, es genial
fuente
Personalicé una ventana emergente personalizada con Rg.Plugins.Popup NuGet, este es un ejemplo:
<pages:PopupPage.Animation> <animations:ScaleAnimation PositionIn="Center" PositionOut="Center" ScaleIn="1.2" ScaleOut="0.8" DurationIn="600" DurationOut="600" EasingIn="Linear" EasingOut="Linear"/> </pages:PopupPage.Animation> <Frame CornerRadius="10" HeightRequest="30" VerticalOptions="End" HorizontalOptions="Fill" HasShadow="False" Padding="0" Margin="40,50" OutlineColor="LightGray"> <StackLayout Opacity="0.4" BackgroundColor="White"> <Label x:Name="lbl" LineBreakMode="WordWrap" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" TextColor="Black" FontSize="12"> <Label.FontFamily> <OnPlatform x:TypeArguments="x:String"> <On Platform="iOS" Value="NewJuneMedium" /> </OnPlatform> </Label.FontFamily> </Label> </StackLayout> </Frame>
luego en su página de contenido base puede agregar el siguiente código, para mostrar y ocultar el "brindis" después de un tiempo:
public async void showpopup(string msg) { await Navigation.PushPopupAsync(new Toast(msg)); await Task.Delay(3000); await Navigation.PopPopupAsync(true); }
fuente
Las respuestas de iOS anteriores funcionaron para mí, pero por un pequeño problema: una advertencia: ¡Intente presentar UIAlertController ... cuya vista no está en la jerarquía de ventanas!
Después de una búsqueda, encontré esta respuesta no relacionada que ayudó. El cartel comentó "Esto parece estúpido pero funciona", lo cual es correcto en ambos aspectos.
Entonces, modifiqué la función ShowAlert () anterior con estas líneas, que parecen funcionar:
var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController; while ( rootVC.PresentedViewController != null) { rootVC = rootVC.PresentedViewController; } rootVC.PresentViewController( alert, true, null);
fuente
Para UWP
public void ShowMessageFast(string message) { ToastNotifier ToastNotifier = ToastNotificationManager.CreateToastNotifier(); Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02); Windows.Data.Xml.Dom.XmlNodeList toastNodeList = toastXml.GetElementsByTagName("text"); toastNodeList.Item(0).AppendChild(toastXml.CreateTextNode("Test")); toastNodeList.Item(1).AppendChild(toastXml.CreateTextNode(message)); Windows.Data.Xml.Dom.IXmlNode toastNode = toastXml.SelectSingleNode("/toast"); Windows.Data.Xml.Dom.XmlElement audio = toastXml.CreateElement("audio"); audio.SetAttribute("src", "ms-winsoundevent:Notification.SMS"); ToastNotification toast = new ToastNotification(toastXml); toast.ExpirationTime = DateTime.Now.AddSeconds(4); ToastNotifier.Show(toast); }
fuente
Puedes usar
DisplayAlert("", "", "", "" );
fuente