Xamarin Forms에 해당하는 토스트
Android 또는 iOS 전용이 아닌 Xamarin Forms를 사용하여 Android가 Toast에서 수행하는 것처럼 사용자 상호 작용이 필요하지 않고 (짧은) 시간이 지나면 사라지는 팝업을 표시하는 방법이 있습니까?
주변을 검색하면 사용자가 클릭해야하는 알림이 표시됩니다.
이에 대한 간단한 해결책이 있습니다. DependencyService 를 사용하면 Android와 iOS 모두에서 Toast-Like 접근 방식을 쉽게 얻을 수 있습니다.
공통 패키지에 인터페이스를 만듭니다.
public interface IMessage
{
void LongAlert(string message);
void ShortAlert(string message);
}
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();
}
}
}
iOS 섹션
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에 클래스를 등록해야합니다.
이제 프로젝트의 어느 곳에서나 토스트 서비스에 액세스 할 수 있습니다.
DependencyService.Get<IMessage>().ShortAlert(string message);
DependencyService.Get<IMessage>().LongAlert(string message);
다음 은 여러 메시지가 표시 될 때 UI 고정을 방지하는 Alex Chengalan의 iOS 코드 버전입니다 .
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
실제로 높이를 최소로 유지하는 데 필요합니다.
다음은 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();
}
우리는 일반적으로 Egors Toasts 플러그인을 사용하지만 현재 프로젝트의 iOS에 대한 권한이 필요하기 때문에 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">
...
앱 시작시 등록하거나 Xamarin.Forms.DependencyService를 사용하여 서비스를 가져 오는 인터페이스도 사용할 수있는 서비스에 의해 생성됩니다.
The service news up the PopupPage derived page, and does
await PopupNavigation.PushAsync(newToastPage);
await Task.Delay(2000);
await PopupNavigation.PopAllAsync();
The Popup page can be dismissed by the user by tapping outside the page display (assuming it hasn't filled the screen).
This seems to work happily on iOS/Droid, but I'm open to correction if anyone knows what this is a risky way of doing it.
@MengTim, to fix the multiple toast issue in @alex-chengalan's solution, I simply wrapped everything within ShowAlert() with a check to see if alert and alertDelay are null, then within DismissMessage, nulled out alert and 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;
}
}
That seemed to at least clear up the UI hang, if you are looking for a quick fix. I was trying to display the toast on navigation to a new page, and believe that the PresentViewController being set was essentially cancelling out my navigation. Sorry I did not comment within the thread, my reputation is too low :(
You can use Acr.UserDialogs Package from nuget and code like below,
Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));
There is no built-in mechanism in Forms, but this nuget package supplies something similar
https://github.com/EgorBo/Toasts.Forms.Plugin
Note: These are not Android style toasts as requested in the question but UWP style toasts which are system wide notifications.
This is my improved ShowAlert
version of Ian Warburton's version to ensure that the toast is displayed even on popup page. Furthermore, the toast is dissmissed if the user click outside the toast. I used UIAlertControllerStyle.ActionSheet
that look likes toast but it also work with UIAlertControllerStyle.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);
});
}
I hope this will help someone !
You can use IUserDialog NuGet and simply use it's toastAlert
var toastConfig = new ToastConfig("Toasting...");
toastConfig.SetDuration(3000);
toastConfig.SetBackgroundColor(System.Drawing.Color.FromArgb(12, 131, 193));
UserDialogs.Instance.Toast(toastConfig);
The iOS answers above worked for me but for one little problem -- a warning: Attempt to present UIAlertController ... whose view is not in the window hierarchy!
After some search, I came across this unrelated answer which helped. The poster commented "This looks stupid but works", which is right on both counts.
So, I modified the ShowAlert() function above with these lines, which seem to work:
var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
while ( rootVC.PresentedViewController != null) {
rootVC = rootVC.PresentedViewController;
}
rootVC.PresentViewController( alert, true, null);
For 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);
}
Check plugin.toast v 2.1.2 available for android, iOS and UWP
You can use DisplayAlert("", "", "", "" );
참고URL : https://stackoverflow.com/questions/35279403/toast-equivalent-for-xamarin-forms
'developer tip' 카테고리의 다른 글
Apple Development Push Services의 개인 키를 찾을 수 없습니다. (0) | 2020.12.14 |
---|---|
Node js 오류 : 프로토콜“https :”가 지원되지 않습니다. (0) | 2020.12.14 |
Angular2 : 정의되지 않은 '이름'속성을 읽을 수 없습니다. (0) | 2020.12.14 |
MySql 5.7 설치 프로그램이 VS 2013 재배포 가능 패키지를 감지하지 못함 (0) | 2020.12.14 |
UIViewController가 탐색 스택에서 Popped를 가져 오는지 확인하고 있습니까? (0) | 2020.12.14 |