From 99d5f152f6363144fb2395d2828ed463633ca96b Mon Sep 17 00:00:00 2001 From: Benjamin Mayrargue Date: Wed, 19 Apr 2023 12:33:14 +0200 Subject: [PATCH 1/5] upgrade WaitIndicator iOS. Upgrade to .net7. Add .netstandard compatibility. Start add xamarin.ios compatibility. --- UserInteractionDemo/MainViewModel.cs | 20 ++- .../UserInteractionDemo.csproj | 2 +- .../IWaitIndicator.shared.cs | 33 ++-- .../InputResponse.shared.cs | 14 +- .../ToastDuration.shared.cs | 15 +- Vapolia.UserInteraction/ToastStyle.shared.cs | 29 +-- .../UserInteraction.android.cs | 54 ++++-- .../UserInteraction.ios.cs | 79 ++++---- .../UserInteraction.shared.cs | 169 +++++++++--------- .../Vapolia.UserInteraction.csproj | 25 ++- 10 files changed, 239 insertions(+), 201 deletions(-) diff --git a/UserInteractionDemo/MainViewModel.cs b/UserInteractionDemo/MainViewModel.cs index da3cdce..b73727d 100644 --- a/UserInteractionDemo/MainViewModel.cs +++ b/UserInteractionDemo/MainViewModel.cs @@ -7,13 +7,16 @@ public class MainViewModel { public ICommand AlertCommand { get; } public ICommand MenuCommand { get; } - public object ToastCommand { get; } - public object ConfirmCommand { get; } - public object Confirm3Command { get; } + public ICommand ToastCommand { get; } + public ICommand ConfirmCommand { get; } + public ICommand Confirm3Command { get; } public MainViewModel() { - AlertCommand = new Command(async () => { await UserInteraction.Alert("This is a message", "Optional title", "OK"); }); + AlertCommand = new Command(async () => + { + await UserInteraction.Alert("This is a message", "Optional title", "OK"); + }); MenuCommand = new Command(async () => { @@ -25,12 +28,16 @@ public MainViewModel() 2 => "Option 1", 3 => "Option 2", 4 => "Option 3", + _ => throw new NotSupportedException() }; await UserInteraction.Alert(text, "Selected item is:", "Close"); }); - ToastCommand = new Command(async () => { await UserInteraction.Toast("This is a message", ToastStyle.Warning, ToastDuration.Normal, ToastPosition.Bottom, 100); }); + ToastCommand = new Command(async () => + { + await UserInteraction.Toast("This is a message", ToastStyle.Warning, ToastDuration.Normal, ToastPosition.Bottom, 100); + }); ConfirmCommand = new Command(async () => { @@ -45,7 +52,8 @@ public MainViewModel() { ConfirmThreeButtonsResponse.Negative => "Cancelled", ConfirmThreeButtonsResponse.Positive => "Done!", - ConfirmThreeButtonsResponse.Neutral => "I'll ask you later!" + ConfirmThreeButtonsResponse.Neutral => "I'll ask you later!", + _ => throw new NotSupportedException() }; await UserInteraction.Toast(text, ToastStyle.Notice); }); diff --git a/UserInteractionDemo/UserInteractionDemo.csproj b/UserInteractionDemo/UserInteractionDemo.csproj index 8115e3a..b1168ec 100644 --- a/UserInteractionDemo/UserInteractionDemo.csproj +++ b/UserInteractionDemo/UserInteractionDemo.csproj @@ -1,7 +1,7 @@  - net6.0-android;net6.0-ios + net7.0-android;net7.0-ios Exe UserInteractionDemo true diff --git a/Vapolia.UserInteraction/IWaitIndicator.shared.cs b/Vapolia.UserInteraction/IWaitIndicator.shared.cs index cb07a57..7fd3f5d 100644 --- a/Vapolia.UserInteraction/IWaitIndicator.shared.cs +++ b/Vapolia.UserInteraction/IWaitIndicator.shared.cs @@ -1,22 +1,21 @@ using System.Threading; -namespace Vapolia.UserInteraction +namespace Vapolia.UserInteraction; + +public interface IWaitIndicator { - public interface IWaitIndicator - { - /// - /// cancelled if the indicator is dismissed by the user (if userCanDismiss is true) - /// - CancellationToken UserDismissedToken { get; } + /// + /// cancelled if the indicator is dismissed by the user (if userCanDismiss is true) + /// + CancellationToken UserDismissedToken { get; } - /// - /// Update the title text while displayed - /// - string Title { set; } + /// + /// Update the title text while displayed + /// + string Title { set; } - /// - /// Update the body text while displayed - /// - string Body { set; } - } -} + /// + /// Update the body text while displayed + /// + string Body { set; } +} \ No newline at end of file diff --git a/Vapolia.UserInteraction/InputResponse.shared.cs b/Vapolia.UserInteraction/InputResponse.shared.cs index d961d78..9d65a87 100644 --- a/Vapolia.UserInteraction/InputResponse.shared.cs +++ b/Vapolia.UserInteraction/InputResponse.shared.cs @@ -1,9 +1,7 @@ -namespace Vapolia.UserInteraction -{ - public class InputResponse - { - public bool Ok { get; set; } - public string? Text { get; set;} - } -} +namespace Vapolia.UserInteraction; +public class InputResponse +{ + public bool Ok { get; set; } + public string? Text { get; set;} +} \ No newline at end of file diff --git a/Vapolia.UserInteraction/ToastDuration.shared.cs b/Vapolia.UserInteraction/ToastDuration.shared.cs index 794052f..ef5590f 100644 --- a/Vapolia.UserInteraction/ToastDuration.shared.cs +++ b/Vapolia.UserInteraction/ToastDuration.shared.cs @@ -1,9 +1,8 @@ -namespace Vapolia.UserInteraction +namespace Vapolia.UserInteraction; + +public enum ToastDuration { - public enum ToastDuration - { - Short = 1000, - Normal = 2500, - Long = 8000 - } -} + Short = 1000, + Normal = 2500, + Long = 8000 +} \ No newline at end of file diff --git a/Vapolia.UserInteraction/ToastStyle.shared.cs b/Vapolia.UserInteraction/ToastStyle.shared.cs index 9f5fef7..6bed991 100644 --- a/Vapolia.UserInteraction/ToastStyle.shared.cs +++ b/Vapolia.UserInteraction/ToastStyle.shared.cs @@ -1,23 +1,10 @@ -namespace Vapolia.UserInteraction -{ - public enum ToastStyle - { - Custom, - Info, - Notice, - Warning, - Error - } +namespace Vapolia.UserInteraction; - public static class Constants - { - public static Color[] ToastStyleBackgroundTint = - { - null, - null, - null, - Colors.Orange, - Colors.Red, - }; - } +public enum ToastStyle +{ + Custom, + Info, + Notice, + Warning, + Error } diff --git a/Vapolia.UserInteraction/UserInteraction.android.cs b/Vapolia.UserInteraction/UserInteraction.android.cs index e17a266..b1ddcd3 100644 --- a/Vapolia.UserInteraction/UserInteraction.android.cs +++ b/Vapolia.UserInteraction/UserInteraction.android.cs @@ -22,6 +22,19 @@ namespace Vapolia.UserInteraction; + +public static class Constants +{ + public static Microsoft.Maui.Graphics.Color?[] ToastStyleBackgroundTint = + { + null, + null, + null, + Colors.Orange, + Colors.Red, + }; +} + public partial class UserInteraction { /// @@ -262,7 +275,7 @@ public string? Body } } - internal static IWaitIndicator PlatformWaitIndicator(CancellationToken dismiss, string? message, string? title, int? displayAfterSeconds, bool userCanDismiss) + static IWaitIndicator PlatformWaitIndicator(CancellationToken dismiss, string? message, string? title, int? displayAfterSeconds, bool userCanDismiss) { var cancellationTokenSource = new CancellationTokenSource(); var wi = new WaitIndicatorImpl(cancellationTokenSource.Token) @@ -270,8 +283,23 @@ internal static IWaitIndicator PlatformWaitIndicator(CancellationToken dismiss, Title = title, Body = message }; + + if(displayAfterSeconds is null or 0) + Do(); + else + { + try + { + Task.Delay(displayAfterSeconds.Value*1000, dismiss).ContinueWith(_ => Do(), TaskContinuationOptions.OnlyOnRanToCompletion); + } + catch (TaskCanceledException) + { + } + } + + return wi; - Task.Delay((displayAfterSeconds ?? 0)*1000, dismiss).ContinueWith(t => + void Do() { var activity = CurrentActivity; @@ -285,11 +313,15 @@ internal static IWaitIndicator PlatformWaitIndicator(CancellationToken dismiss, var dialog = new MaterialAlertDialogBuilder(activity) .SetTitle(wi.Title) - .SetMessage(wi.Body) - .SetView(input) - .SetCancelable(userCanDismiss) - .SetOnCancelListener(new DialogCancelledListener(cancellationTokenSource.Cancel)) - .Create(); + ?.SetMessage(wi.Body) + ?.SetView(input) + ?.SetCancelable(userCanDismiss) + ?.SetOnCancelListener(new DialogCancelledListener(cancellationTokenSource.Cancel)) + ?.Create(); + + if (dialog == null) + throw new("UserInteraction can't create dialog, MaterialAlertDialogBuilder returned null."); + dialog.SetCanceledOnTouchOutside(userCanDismiss); //dialog.CancelEvent += delegate { cancellationTokenSource.Cancel(); }; @@ -302,9 +334,7 @@ internal static IWaitIndicator PlatformWaitIndicator(CancellationToken dismiss, activity.RunOnUiThread(dialog.Dismiss); }); }); - }, TaskContinuationOptions.OnlyOnRanToCompletion); - - return wi; + } } class DialogDismissListener : Java.Lang.Object, IDialogInterfaceOnDismissListener @@ -318,7 +348,7 @@ public void OnDismiss(IDialogInterface? dialog) => onDismiss(); } - internal static Task PlatformActivityIndicator(CancellationToken dismiss, double? apparitionDelay, uint? argbColor) + static Task PlatformActivityIndicator(CancellationToken dismiss, double? apparitionDelay, uint? argbColor) { var tcs = new TaskCompletionSource(); @@ -509,7 +539,7 @@ internal static Task PlatformToast(string text, ToastStyle style = ToastStyle.No var activity = CurrentActivity; var view = activity?.Window?.DecorView.RootView; - if (view != null) + if (activity != null && view != null) { activity.RunOnUiThread(() => { diff --git a/Vapolia.UserInteraction/UserInteraction.ios.cs b/Vapolia.UserInteraction/UserInteraction.ios.cs index 3df5c04..7c8e6d4 100644 --- a/Vapolia.UserInteraction/UserInteraction.ios.cs +++ b/Vapolia.UserInteraction/UserInteraction.ios.cs @@ -157,7 +157,7 @@ class WaitIndicatorImpl : IWaitIndicator { private string? title, body; - public UIAlertView? Dialog { get; set; } + public UIAlertController? Dialog { get; set; } public WaitIndicatorImpl(CancellationToken userDismissedToken) { @@ -177,50 +177,61 @@ public WaitIndicatorImpl(CancellationToken userDismissedToken) /// delay show. Can be cancelled before it is displayed. /// Enable tap to dismiss /// CancellationToken is cancelled if the indicator is dismissed by the user (if userCanDismiss is true) - internal static IWaitIndicator PlatformWaitIndicator(CancellationToken dismiss, string? message = null, string? title=null, int? displayAfterSeconds = null, bool userCanDismiss = true) + /// + /// This should block the UI if userCanDismiss is false + /// + static IWaitIndicator PlatformWaitIndicator(CancellationToken dismiss, string? message = null, string? title=null, int? displayAfterSeconds = null, bool userCanDismiss = true) { - var cancellationTokenSource = new CancellationTokenSource(); - var wi = new WaitIndicatorImpl(cancellationTokenSource.Token) + var userDismissed = new CancellationTokenSource(); + var wi = new WaitIndicatorImpl(userDismissed.Token) { Title = title, Body = message }; - - //var currentView = Mvx.Resolve(); - - Task.Delay((displayAfterSeconds ?? 0)*1000, dismiss).ContinueWith(t => UIApplication.SharedApplication.InvokeOnMainThread(() => + + if(displayAfterSeconds is null or 0) + Do(); + else { - var input = new UIAlertView { Title = wi.Title ?? string.Empty, Message = wi.Body ?? string.Empty }; - wi.Dialog = input; - - //Adding an indicator by either of these 2 methods won't work. Why ? - - //var indicator = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.WhiteLarge); - //input.Add(indicator); - - //var indicator = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.WhiteLarge) { TranslatesAutoresizingMaskIntoConstraints = false }; - //input.Add(indicator); - //input.AddConstraint(NSLayoutConstraint.Create(indicator, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, input, NSLayoutAttribute.CenterX, 1, 0)); - ////input.AddConstraint(NSLayoutConstraint.Create(indicator, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, input, NSLayoutAttribute.CenterY, 1, 0)); - //input.AddConstraint(NSLayoutConstraint.Create(indicator, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 50)); - //input.AddConstraint(NSLayoutConstraint.Create(indicator, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 50)); - - if(userCanDismiss) - input.Clicked += (s,e) => cancellationTokenSource.Cancel(); - - input.BackgroundColor = UIColor.FromWhiteAlpha(0, 0); - input.Show(); + try + { + Task.Delay(displayAfterSeconds.Value*1000, dismiss).ContinueWith(_ => Do(), TaskContinuationOptions.OnlyOnRanToCompletion); + } + catch (TaskCanceledException) + { + } + } + + return wi; - dismiss.Register(() => UIApplication.SharedApplication.InvokeOnMainThread(() => input.DismissWithClickedButtonIndex(0, true)), true); + void Do() + { + UIApplication.SharedApplication.InvokeOnMainThread(() => + { + var alert = UIAlertController.Create(title ?? string.Empty, message, UIAlertControllerStyle.Alert); + wi.Dialog = alert; + if (userCanDismiss) + alert.AddAction(UIAlertAction.Create("X", UIAlertActionStyle.Cancel, _ => userDismissed.Cancel())); - //TODO: dismiss if app goes into background mode - //NSNotificationCenter.UIApplicationDidEnterBackgroundNotification - }), TaskContinuationOptions.NotOnCanceled); + dismiss.Register(() => UIApplication.SharedApplication.InvokeOnMainThread(() => + { + if(alert.ParentViewController != null) + alert.DismissViewController(true, null); + }), true); - return wi; + var presentingVc = Platform.GetCurrentUIViewController(); + if (presentingVc != null) + UIApplication.SharedApplication.InvokeOnMainThread(() => + { + presentingVc.PresentViewController(alert, true, null); + }); + else + Log?.LogWarning("Input: no window/nav controller on which to display"); + }); + } } - internal static Task PlatformActivityIndicator(CancellationToken dismiss, double? apparitionDelay = null, uint? argbColor = null) + static Task PlatformActivityIndicator(CancellationToken dismiss, double? apparitionDelay = null, uint? argbColor = null) { var presentingVc = Platform.GetCurrentUIViewController(); if (presentingVc == null) diff --git a/Vapolia.UserInteraction/UserInteraction.shared.cs b/Vapolia.UserInteraction/UserInteraction.shared.cs index d59bbc6..8b9904f 100644 --- a/Vapolia.UserInteraction/UserInteraction.shared.cs +++ b/Vapolia.UserInteraction/UserInteraction.shared.cs @@ -1,100 +1,99 @@ using Microsoft.Extensions.Logging; -namespace Vapolia.UserInteraction +namespace Vapolia.UserInteraction; + +public partial class UserInteraction { - public partial class UserInteraction - { - public static ILogger? Log {get;set;} + public static ILogger? Log {get;set;} - /// - /// Set default color for all activity indicators - /// In android use global styles instead. - /// - public static uint DefaultColor { set => PlatformDefaultColor = value; } + /// + /// Set default color for all activity indicators + /// In android use global styles instead. + /// + public static uint DefaultColor { set => PlatformDefaultColor = value; } - public static Task Confirm(string message, string? title = null, string okButton = "OK", string cancelButton = "Cancel", CancellationToken? dismiss = null) - => PlatformConfirm(message, title, okButton, cancelButton, dismiss); + public static Task Confirm(string message, string? title = null, string okButton = "OK", string cancelButton = "Cancel", CancellationToken? dismiss = null) + => PlatformConfirm(message, title, okButton, cancelButton, dismiss); - public static Task Alert(string message, string title = "", string okButton = "OK") - => PlatformAlert(message, title, okButton); + public static Task Alert(string message, string title = "", string okButton = "OK") + => PlatformAlert(message, title, okButton); - public static Task Input(string message, string? defaultValue = null, string? placeholder = null, string? title = null, string okButton = "OK", string cancelButton = "Cancel", FieldType fieldType = FieldType.Default, int maxLength = 0, bool selectContent = true) - => PlatformInput(message, defaultValue, placeholder, title, okButton, cancelButton, fieldType, maxLength, selectContent); + public static Task Input(string message, string? defaultValue = null, string? placeholder = null, string? title = null, string okButton = "OK", string cancelButton = "Cancel", FieldType fieldType = FieldType.Default, int maxLength = 0, bool selectContent = true) + => PlatformInput(message, defaultValue, placeholder, title, okButton, cancelButton, fieldType, maxLength, selectContent); - public static Task ConfirmThreeButtons(string message, string? title = null, string positive = "Yes", string negative = "No", string neutral = "Maybe") - => PlatformConfirmThreeButtons(message, title, positive, negative, neutral); + public static Task ConfirmThreeButtons(string message, string? title = null, string positive = "Yes", string negative = "No", string neutral = "Maybe") + => PlatformConfirmThreeButtons(message, title, positive, negative, neutral); - /// - /// Displays a wait indicator (title + body + indeterminate progress bar) - /// - /// CancellationToken that dismiss the indicator when cancelled - /// body - /// - /// delay show. Can be cancelled before it is displayed. - /// Enable tap to dismiss - /// A controller for the wait indicator - public static IWaitIndicator WaitIndicator(CancellationToken dismiss, string? message = null, string? title=null, int? displayAfterSeconds = null, bool userCanDismiss = true) - => PlatformWaitIndicator(dismiss, message, title, displayAfterSeconds, userCanDismiss); + /// + /// Displays a wait indicator (title + body + indeterminate progress bar) + /// + /// CancellationToken that dismiss the indicator when cancelled + /// body + /// + /// delay show. Can be cancelled before it is displayed. + /// Enable tap to dismiss + /// A controller for the wait indicator + public static IWaitIndicator WaitIndicator(CancellationToken dismiss, string? message = null, string? title=null, int? displayAfterSeconds = null, bool userCanDismiss = true) + => PlatformWaitIndicator(dismiss, message, title, displayAfterSeconds, userCanDismiss); - /// - /// Display an activity indicator which blocks user interaction. - /// - /// cancel this token to dismiss the activity indicator - /// show indicator after this delay. The user interaction is not disabled during this delay: this may be an issue. - /// activity indicator tint - /// - public static Task ActivityIndicator(CancellationToken dismiss, double? apparitionDelay = null, uint? argbColor = null) - => PlatformActivityIndicator(dismiss, apparitionDelay, argbColor); + /// + /// Display an activity indicator which blocks user interaction. + /// + /// cancel this token to dismiss the activity indicator + /// show indicator after this delay. The user interaction is not disabled during this delay: this may be an issue. + /// activity indicator tint + /// + public static Task ActivityIndicator(CancellationToken dismiss, double? apparitionDelay = null, uint? argbColor = null) + => PlatformActivityIndicator(dismiss, apparitionDelay, argbColor); - /// - /// Display a single choice menu - /// - /// optional. Can be used to close the menu programatically. - /// true to allow the user to close the menu using a hardware key. - /// optional absolute position on screen - /// optional title - /// optional description - /// from 2 to 2+number of actions. Otherwise ignored. - /// optional cancel button. If null the cancel button is not shown. - /// optional destroy button. Will be red. - /// If a button is null, the index are still incremented, but the button won't appear - /// - /// A task which completes when the menu has disappeared - /// 0: cancel button or hardware key is pressed - /// 1: destroy button is pressed - /// 2-n: other matching button is pressed - /// - /// - /// If otherButtons is null, the indexes are still incremented, but the button won't appear. - /// This enables easy scenario where the otherButtons array is changing between calls. - /// - public static Task Menu(CancellationToken dismiss, bool userCanDismiss, System.Drawing.RectangleF? position, string? title, string? description = null, int defaultActionIndex = -1, string? cancelButton = null, string? destroyButton = null, params string[] otherButtons) - => PlatformMenu(dismiss, userCanDismiss, position, title, description, defaultActionIndex, cancelButton, destroyButton, otherButtons); + /// + /// Display a single choice menu + /// + /// optional. Can be used to close the menu programatically. + /// true to allow the user to close the menu using a hardware key. + /// optional absolute position on screen + /// optional title + /// optional description + /// from 2 to 2+number of actions. Otherwise ignored. + /// optional cancel button. If null the cancel button is not shown. + /// optional destroy button. Will be red. + /// If a button is null, the index are still incremented, but the button won't appear + /// + /// A task which completes when the menu has disappeared + /// 0: cancel button or hardware key is pressed + /// 1: destroy button is pressed + /// 2-n: other matching button is pressed + /// + /// + /// If otherButtons is null, the indexes are still incremented, but the button won't appear. + /// This enables easy scenario where the otherButtons array is changing between calls. + /// + public static Task Menu(CancellationToken dismiss, bool userCanDismiss, System.Drawing.RectangleF? position, string? title, string? description = null, int defaultActionIndex = -1, string? cancelButton = null, string? destroyButton = null, params string[] otherButtons) + => PlatformMenu(dismiss, userCanDismiss, position, title, description, defaultActionIndex, cancelButton, destroyButton, otherButtons); - /// - /// Shortcut - /// - public static Task Menu(CancellationToken dismiss, bool userCanDismiss, string? title, string? description = null, int defaultActionIndex = -1, string? cancelButton = null, string? destroyButton = null, params string[] otherButtons) - => PlatformMenu(dismiss, userCanDismiss, null, title, description, defaultActionIndex, cancelButton, destroyButton, otherButtons); + /// + /// Shortcut + /// + public static Task Menu(CancellationToken dismiss, bool userCanDismiss, string? title, string? description = null, int defaultActionIndex = -1, string? cancelButton = null, string? destroyButton = null, params string[] otherButtons) + => PlatformMenu(dismiss, userCanDismiss, null, title, description, defaultActionIndex, cancelButton, destroyButton, otherButtons); - /// - /// Shortcut - /// - public static Task Menu(string? title, string? description = null, string? cancelButton = null, string? destroyButton = null, params string[] otherButtons) - => PlatformMenu(CancellationToken.None, true, null, title, description, -1, cancelButton, destroyButton, otherButtons); + /// + /// Shortcut + /// + public static Task Menu(string? title, string? description = null, string? cancelButton = null, string? destroyButton = null, params string[] otherButtons) + => PlatformMenu(CancellationToken.None, true, null, title, description, -1, cancelButton, destroyButton, otherButtons); - /// - /// Display a toast - /// - /// - /// - /// - /// - /// - /// optional. Can be used to close the toast programatically. - /// A task which completes when the toast has disappeared - public static Task Toast(string text, ToastStyle style = ToastStyle.Notice, ToastDuration duration = ToastDuration.Normal, ToastPosition position = ToastPosition.Bottom, int positionOffset = 20, CancellationToken? dismiss = null) - => PlatformToast(text, style, duration, position, positionOffset, dismiss); - } -} + /// + /// Display a toast + /// + /// + /// + /// + /// + /// + /// optional. Can be used to close the toast programatically. + /// A task which completes when the toast has disappeared + public static Task Toast(string text, ToastStyle style = ToastStyle.Notice, ToastDuration duration = ToastDuration.Normal, ToastPosition position = ToastPosition.Bottom, int positionOffset = 20, CancellationToken? dismiss = null) + => PlatformToast(text, style, duration, position, positionOffset, dismiss); +} \ No newline at end of file diff --git a/Vapolia.UserInteraction/Vapolia.UserInteraction.csproj b/Vapolia.UserInteraction/Vapolia.UserInteraction.csproj index 2724eb6..8b24634 100644 --- a/Vapolia.UserInteraction/Vapolia.UserInteraction.csproj +++ b/Vapolia.UserInteraction/Vapolia.UserInteraction.csproj @@ -1,41 +1,47 @@  - - net6.0-android;net6.0-ios + + netstandard2.1;net7.0-android;net7.0-ios;Xamarin.iOS10 Vapolia.UserInteraction Vapolia.UserInteraction false latest enable - true + true enable - 15.0 - 26.0 + 15.0 + 26.0 - + - + - + - + + + + + + + @@ -71,6 +77,7 @@ false https://github.com/softlion/UserInteraction + 1.0.1 replaced ios WaitIndicator from AlertView to UIAlertAction --- version is now 1.0.0 4.0.1: replace android toast by a snackbar, and make its background color customizable. 4.0.0: supports MAUI. Moved location fetcher to a standalone nuget. From 5fd32ca9c2eaad984c91eb97581ef308aac6e97d Mon Sep 17 00:00:00 2001 From: Benjamin Mayrargue Date: Wed, 19 Apr 2023 12:55:00 +0200 Subject: [PATCH 2/5] remove xamarin. test with new PlatformWaitIndicator --- Vapolia.UserInteraction/UserInteraction.ios.cs | 2 +- Vapolia.UserInteraction/Vapolia.UserInteraction.csproj | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Vapolia.UserInteraction/UserInteraction.ios.cs b/Vapolia.UserInteraction/UserInteraction.ios.cs index 7c8e6d4..a10f272 100644 --- a/Vapolia.UserInteraction/UserInteraction.ios.cs +++ b/Vapolia.UserInteraction/UserInteraction.ios.cs @@ -252,7 +252,7 @@ static Task PlatformActivityIndicator(CancellationToken dismiss, double? apparit var waitView = new UIView {Alpha = 0}; var overlay = new UIView {BackgroundColor = UIColor.White, Alpha = 0.7f}; - var indicator = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.WhiteLarge) {HidesWhenStopped = true}; + var indicator = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.Large) {HidesWhenStopped = true}; if (argbColor.HasValue || defaultColor != null) indicator.Color = argbColor.HasValue ? FromArgb(argbColor.Value) : defaultColor; diff --git a/Vapolia.UserInteraction/Vapolia.UserInteraction.csproj b/Vapolia.UserInteraction/Vapolia.UserInteraction.csproj index 8b24634..f097fb4 100644 --- a/Vapolia.UserInteraction/Vapolia.UserInteraction.csproj +++ b/Vapolia.UserInteraction/Vapolia.UserInteraction.csproj @@ -2,7 +2,11 @@ - netstandard2.1;net7.0-android;net7.0-ios;Xamarin.iOS10 + + netstandard2.1;net7.0-android;net7.0-ios Vapolia.UserInteraction Vapolia.UserInteraction false @@ -42,6 +46,7 @@ + From 989d447647b6bf0b98d9328220d4759f9224fd1c Mon Sep 17 00:00:00 2001 From: Benjamin Mayrargue Date: Wed, 19 Apr 2023 14:10:02 +0200 Subject: [PATCH 3/5] dismiss correctly --- Vapolia.UserInteraction/UserInteraction.ios.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Vapolia.UserInteraction/UserInteraction.ios.cs b/Vapolia.UserInteraction/UserInteraction.ios.cs index a10f272..d13c40c 100644 --- a/Vapolia.UserInteraction/UserInteraction.ios.cs +++ b/Vapolia.UserInteraction/UserInteraction.ios.cs @@ -215,8 +215,7 @@ void Do() dismiss.Register(() => UIApplication.SharedApplication.InvokeOnMainThread(() => { - if(alert.ParentViewController != null) - alert.DismissViewController(true, null); + alert.DismissViewController(true, null); }), true); var presentingVc = Platform.GetCurrentUIViewController(); From 3230c5f7096893fdf8d62fbf77aaa59b3bc4c388 Mon Sep 17 00:00:00 2001 From: benjaminMac Date: Wed, 19 Apr 2023 14:13:04 +0200 Subject: [PATCH 4/5] add demo for the wait indicator --- UserInteractionDemo/MainPage.xaml | 1 + UserInteractionDemo/MainViewModel.cs | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/UserInteractionDemo/MainPage.xaml b/UserInteractionDemo/MainPage.xaml index 87bd815..346ba7a 100644 --- a/UserInteractionDemo/MainPage.xaml +++ b/UserInteractionDemo/MainPage.xaml @@ -39,6 +39,7 @@