diff --git a/src/App/App.csproj b/src/App/App.csproj index fdafa7f28..c9ab94f02 100644 --- a/src/App/App.csproj +++ b/src/App/App.csproj @@ -124,6 +124,7 @@ + @@ -411,4 +412,7 @@ + + + diff --git a/src/App/Behaviors/EditorPreventAutoBottomScrollingOnFocusedBehavior.cs b/src/App/Behaviors/EditorPreventAutoBottomScrollingOnFocusedBehavior.cs new file mode 100644 index 000000000..b00f63737 --- /dev/null +++ b/src/App/Behaviors/EditorPreventAutoBottomScrollingOnFocusedBehavior.cs @@ -0,0 +1,43 @@ +using Xamarin.Essentials; +using Xamarin.Forms; + +namespace Bit.App.Behaviors +{ + /// + /// This behavior prevents the Editor to be automatically scrolled to the bottom on focus. + /// This is needed due to this Xamarin Forms issue: https://github.com/xamarin/Xamarin.Forms/issues/2233 + /// + public class EditorPreventAutoBottomScrollingOnFocusedBehavior : Behavior + { + public static readonly BindableProperty ParentScrollViewProperty + = BindableProperty.Create(nameof(ParentScrollView), typeof(ScrollView), typeof(EditorPreventAutoBottomScrollingOnFocusedBehavior)); + + public ScrollView ParentScrollView + { + get => (ScrollView)GetValue(ParentScrollViewProperty); + set => SetValue(ParentScrollViewProperty, value); + } + + protected override void OnAttachedTo(Editor bindable) + { + base.OnAttachedTo(bindable); + + bindable.Focused += OnFocused; + } + + private void OnFocused(object sender, FocusEventArgs e) + { + if (DeviceInfo.Platform.Equals(DevicePlatform.iOS) && ParentScrollView != null) + { + ParentScrollView.ScrollToAsync(ParentScrollView.ScrollX, ParentScrollView.ScrollY, true); + } + } + + protected override void OnDetachingFrom(Editor bindable) + { + bindable.Focused -= OnFocused; + + base.OnDetachingFrom(bindable); + } + } +} diff --git a/src/App/Effects/ScrollEnabledEffect.cs b/src/App/Effects/ScrollEnabledEffect.cs new file mode 100644 index 000000000..dd488f698 --- /dev/null +++ b/src/App/Effects/ScrollEnabledEffect.cs @@ -0,0 +1,25 @@ +using Xamarin.Forms; + +namespace Bit.App.Effects +{ + public class ScrollEnabledEffect : RoutingEffect + { + public static readonly BindableProperty IsScrollEnabledProperty = + BindableProperty.CreateAttached("IsScrollEnabled", typeof(bool), typeof(ScrollEnabledEffect), true); + + public static bool GetIsScrollEnabled(BindableObject view) + { + return (bool)view.GetValue(IsScrollEnabledProperty); + } + + public static void SetIsScrollEnabled(BindableObject view, bool value) + { + view.SetValue(IsScrollEnabledProperty, value); + } + + public ScrollEnabledEffect() + : base("Bitwarden.ScrollEnabledEffect") + { + } + } +} diff --git a/src/App/Pages/Send/SendAddEditPage.xaml b/src/App/Pages/Send/SendAddEditPage.xaml index dd9882ba3..9568a78d7 100644 --- a/src/App/Pages/Send/SendAddEditPage.xaml +++ b/src/App/Pages/Send/SendAddEditPage.xaml @@ -6,6 +6,8 @@ xmlns:pages="clr-namespace:Bit.App.Pages" xmlns:u="clr-namespace:Bit.App.Utilities" xmlns:controls="clr-namespace:Bit.App.Controls" + xmlns:behaviors="clr-namespace:Bit.App.Behaviors" + xmlns:effects="clr-namespace:Bit.App.Effects" x:DataType="pages:SendAddEditPageViewModel" x:Name="_page" Title="{Binding PageTitle}"> @@ -201,7 +203,15 @@ Text="{Binding Send.Text.Text}" IsEnabled="{Binding SendEnabled}" StyleClass="box-value" - Margin="{Binding EditorMargins}" /> + Margin="{Binding EditorMargins}" + effects:ScrollEnabledEffect.IsScrollEnabled="false" > + + + + + + + @@ -443,7 +453,15 @@ Text="{Binding Send.Notes}" IsEnabled="{Binding SendEnabled}" StyleClass="box-value" - Margin="{Binding EditorMargins}" /> + Margin="{Binding EditorMargins}" + effects:ScrollEnabledEffect.IsScrollEnabled="false" > + + + + + + + diff --git a/src/App/Pages/Vault/AddEditPage.xaml b/src/App/Pages/Vault/AddEditPage.xaml index 3b7363cc1..dec840fe6 100644 --- a/src/App/Pages/Vault/AddEditPage.xaml +++ b/src/App/Pages/Vault/AddEditPage.xaml @@ -7,6 +7,8 @@ xmlns:u="clr-namespace:Bit.App.Utilities" xmlns:controls="clr-namespace:Bit.App.Controls" xmlns:views="clr-namespace:Bit.Core.Models.View;assembly=BitwardenCore" + xmlns:behaviors="clr-namespace:Bit.App.Behaviors" + xmlns:effects="clr-namespace:Bit.App.Effects" x:DataType="pages:AddEditPageViewModel" x:Name="_page" Title="{Binding PageTitle}"> @@ -584,8 +586,16 @@ + StyleClass="box-value" + effects:ScrollEnabledEffect.IsScrollEnabled="false" + Text="{Binding Cipher.Notes}"> + + + + + + + diff --git a/src/iOS.Core/Effects/ScrollEnabledEffect.cs b/src/iOS.Core/Effects/ScrollEnabledEffect.cs new file mode 100644 index 000000000..13fde6994 --- /dev/null +++ b/src/iOS.Core/Effects/ScrollEnabledEffect.cs @@ -0,0 +1,25 @@ +using Bit.iOS.Core.Effects; +using UIKit; +using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; + +[assembly: ResolutionGroupName("Bitwarden")] +[assembly: ExportEffect(typeof(ScrollEnabledEffect), "ScrollEnabledEffect")] +namespace Bit.iOS.Core.Effects +{ + public class ScrollEnabledEffect : PlatformEffect + { + protected override void OnAttached() + { + // this can be for any view that inherits from UIScrollView like UITextView. + if (Element != null && Control is UIScrollView scrollView) + { + scrollView.ScrollEnabled = App.Effects.ScrollEnabledEffect.GetIsScrollEnabled(Element); + } + } + + protected override void OnDetached() + { + } + } +} diff --git a/src/iOS.Core/iOS.Core.csproj b/src/iOS.Core/iOS.Core.csproj index 3fb702ac7..219264ad5 100644 --- a/src/iOS.Core/iOS.Core.csproj +++ b/src/iOS.Core/iOS.Core.csproj @@ -137,6 +137,7 @@ + @@ -189,6 +190,7 @@ +