是否有任何方法使用Xamarin Forms(不是Android或iOS特定的)来弹出,就像Android与Toast一样,不需要用户交互,并在(短)时间后消失?
从搜索所有我看到的是需要用户点击消失的警报 .
这是我用来在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(); }
我们'd normally use Egors Toasts plugin, but as it requires permissions on iOS for a current project we'使用Rg.Plugins.Popup nuget(https://github.com/rotorgames/Rg.Plugins.Popup)走了一条不同的路线 .
我写了一个类型为PopupPage的基本xaml / cs页面,
<?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"> ...
并让它由服务创建,您在app开始注册的接口或使用Xamarin.Forms.DependencyService来获取服务也是可行的 .
PopupPage派生页面上的服务新闻,并且确实如此
await PopupNavigation.PushAsync(newToastPage); await Task.Delay(2000); await PopupNavigation.PopAllAsync();
用户可以通过点击页面显示外部来取消弹出页面(假设它没有填满屏幕) .
这似乎在iOS / Droid上工作愉快,但如果有人知道这是一种冒险的方法,我愿意纠正 .
@MengTim,为了修复@ alex-chengalan解决方案中的多个Toast问题,我只是在ShowAlert()中包装所有内容,检查alert和alertDelay是否为null,然后在DismissMessage中,取消alert和alertDelay .
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; } }
如果您正在寻找快速解决方案,那似乎至少可以清除UI挂起 . 我试图在导航到新页面时显示吐司,并且相信正在设置的PresentViewController基本上取消了我的导航 . 对不起,我没有在帖子内发表评论,我的名声太低了:(
Forms中没有内置机制,但是这个nuget包提供了类似的东西
https://github.com/EgorBo/Toasts.Forms.Plugin
注意:这些不是问题中所要求的Android风格的祝酒词,而是UWP样式的祝酒词,它们是系统范围的通知 .
这里's a version of Alex Chengalan'的iOS code避免了在显示多条消息时UI粘滞...
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(); } } }
除了Alex的回答,这里是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(); } }
着色和造型取决于您, MaxHeight 实际上需要将高度保持在最低限度 .
MaxHeight
有一个简单的解决方案 . 通过使用DependencyService,您可以轻松地在Android和iOS中获得Toast-Like方法 .
Create an interface in your common package.
public interface IMessage { void LongAlert(string message); void ShortAlert(string message); }
Android section
[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(); } } }
iOS section
在iOs中没有像Toast这样的原生解决方案,所以我们需要实现自己的方法 .
[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(); } } } }
请注意,在每个平台中,我们必须使用DependencyService注册我们的类 .
现在,您可以在我们项目的任何位置访问Toast服务 .
DependencyService.Get<IMessage>().ShortAlert(string message); DependencyService.Get<IMessage>().LongAlert(string message);
7 回答
这是我用来在Xamarin.iOS中显示吐司的代码片段
我们'd normally use Egors Toasts plugin, but as it requires permissions on iOS for a current project we'使用Rg.Plugins.Popup nuget(https://github.com/rotorgames/Rg.Plugins.Popup)走了一条不同的路线 .
我写了一个类型为PopupPage的基本xaml / cs页面,
并让它由服务创建,您在app开始注册的接口或使用Xamarin.Forms.DependencyService来获取服务也是可行的 .
PopupPage派生页面上的服务新闻,并且确实如此
用户可以通过点击页面显示外部来取消弹出页面(假设它没有填满屏幕) .
这似乎在iOS / Droid上工作愉快,但如果有人知道这是一种冒险的方法,我愿意纠正 .
@MengTim,为了修复@ alex-chengalan解决方案中的多个Toast问题,我只是在ShowAlert()中包装所有内容,检查alert和alertDelay是否为null,然后在DismissMessage中,取消alert和alertDelay .
如果您正在寻找快速解决方案,那似乎至少可以清除UI挂起 . 我试图在导航到新页面时显示吐司,并且相信正在设置的PresentViewController基本上取消了我的导航 . 对不起,我没有在帖子内发表评论,我的名声太低了:(
Forms中没有内置机制,但是这个nuget包提供了类似的东西
https://github.com/EgorBo/Toasts.Forms.Plugin
注意:这些不是问题中所要求的Android风格的祝酒词,而是UWP样式的祝酒词,它们是系统范围的通知 .
这里's a version of Alex Chengalan'的iOS code避免了在显示多条消息时UI粘滞...
除了Alex的回答,这里是UWP变体:
着色和造型取决于您,
MaxHeight
实际上需要将高度保持在最低限度 .有一个简单的解决方案 . 通过使用DependencyService,您可以轻松地在Android和iOS中获得Toast-Like方法 .
Create an interface in your common package.
Android section
iOS section
在iOs中没有像Toast这样的原生解决方案,所以我们需要实现自己的方法 .
请注意,在每个平台中,我们必须使用DependencyService注册我们的类 .
现在,您可以在我们项目的任何位置访问Toast服务 .