diff --git a/src/Android/Android.csproj b/src/Android/Android.csproj
index 0bad52e06..9896a4d75 100644
--- a/src/Android/Android.csproj
+++ b/src/Android/Android.csproj
@@ -259,6 +259,7 @@
+
diff --git a/src/Android/MainApplication.cs b/src/Android/MainApplication.cs
index deb3a6c39..e04ee560d 100644
--- a/src/Android/MainApplication.cs
+++ b/src/Android/MainApplication.cs
@@ -122,6 +122,7 @@ namespace Bit.Android
.RegisterType(new ContainerControlledLifetimeManager())
.RegisterType(new ContainerControlledLifetimeManager())
.RegisterType(new ContainerControlledLifetimeManager())
+ .RegisterType(new ContainerControlledLifetimeManager())
// Repositories
.RegisterType(new ContainerControlledLifetimeManager())
.RegisterType(new ContainerControlledLifetimeManager())
diff --git a/src/Android/Services/ReflectionService.cs b/src/Android/Services/ReflectionService.cs
new file mode 100644
index 000000000..4685f4c13
--- /dev/null
+++ b/src/Android/Services/ReflectionService.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Reflection;
+using Bit.App.Abstractions;
+using Bit.App.Controls;
+using Xamarin.Forms;
+
+namespace Bit.Android.Services
+{
+ public class ReflectionService : IReflectionService
+ {
+ public Func GetVisualElementOnSizeRequest(ExtendedTableView tableView)
+ {
+ var handle = typeof(VisualElement).GetMethod(
+ "OnSizeRequest",
+ BindingFlags.Instance | BindingFlags.NonPublic,
+ null,
+ new Type[] { typeof(double), typeof(double) },
+ null)?.MethodHandle;
+
+ if(!handle.HasValue)
+ {
+ throw new ArgumentNullException("handle could not be found.");
+ }
+
+ var pointer = handle.Value.GetFunctionPointer();
+ if(pointer == null)
+ {
+ throw new ArgumentNullException("pointer could not be found.");
+ }
+
+ return (Func)Activator.CreateInstance(typeof(Func), tableView, pointer);
+ }
+ }
+}
diff --git a/src/App/Abstractions/Services/IReflectionService.cs b/src/App/Abstractions/Services/IReflectionService.cs
new file mode 100644
index 000000000..eae6232a8
--- /dev/null
+++ b/src/App/Abstractions/Services/IReflectionService.cs
@@ -0,0 +1,11 @@
+using System;
+using Bit.App.Controls;
+using Xamarin.Forms;
+
+namespace Bit.App.Abstractions
+{
+ public interface IReflectionService
+ {
+ Func GetVisualElementOnSizeRequest(ExtendedTableView tableView);
+ }
+}
diff --git a/src/App/App.csproj b/src/App/App.csproj
index 595fb610d..7faf81742 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -40,6 +40,7 @@
+
diff --git a/src/App/Controls/ExtendedTableView.cs b/src/App/Controls/ExtendedTableView.cs
index 550fcad3f..ced2510fe 100644
--- a/src/App/Controls/ExtendedTableView.cs
+++ b/src/App/Controls/ExtendedTableView.cs
@@ -1,10 +1,21 @@
using System;
using Xamarin.Forms;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+using XLabs.Ioc;
+using Bit.App.Abstractions;
namespace Bit.App.Controls
{
public class ExtendedTableView : TableView
{
+ public ExtendedTableView()
+ : base()
+ {
+ VerticalOptions = LayoutOptions.Start;
+ }
+
public static readonly BindableProperty EnableScrollingProperty =
BindableProperty.Create(nameof(EnableScrolling), typeof(bool), typeof(ExtendedTableView), true);
@@ -33,5 +44,17 @@ namespace Bit.App.Controls
}
public int EstimatedRowHeight { get; set; }
+
+ protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint)
+ {
+ if(Device.OS == TargetPlatform.iOS && VerticalOptions.Alignment != LayoutAlignment.Fill)
+ {
+ var reflectionService = Resolver.Resolve();
+ var baseBaseOnSizeRequest = reflectionService.GetVisualElementOnSizeRequest(this);
+ return baseBaseOnSizeRequest(widthConstraint, heightConstraint);
+ }
+
+ return base.OnSizeRequest(widthConstraint, heightConstraint);
+ }
}
}
diff --git a/src/App/Pages/Settings/SettingsEditFolderPage.cs b/src/App/Pages/Settings/SettingsEditFolderPage.cs
index 5ebc7044e..b78f322fe 100644
--- a/src/App/Pages/Settings/SettingsEditFolderPage.cs
+++ b/src/App/Pages/Settings/SettingsEditFolderPage.cs
@@ -47,6 +47,9 @@ namespace Bit.App.Pages
EnableScrolling = false,
EnableSelection = false,
HasUnevenRows = true,
+ VerticalOptions = LayoutOptions.Start,
+ BackgroundColor = Color.Gray,
+ Margin = new Thickness(0, -1),
Root = new TableRoot
{
new TableSection()
@@ -67,6 +70,9 @@ namespace Bit.App.Pages
Intent = TableIntent.Settings,
EnableScrolling = false,
EnableSelection = true,
+ VerticalOptions = LayoutOptions.End,
+ BackgroundColor = Color.Yellow,
+ Margin = new Thickness(0, -1),
Root = new TableRoot
{
new TableSection()
@@ -102,7 +108,7 @@ namespace Bit.App.Pages
}, ToolbarItemOrder.Default, 0);
Title = "Edit Folder";
- Content = new StackLayout { Children = { mainTable, deleteTable } };
+ Content = new ScrollView { Content = new StackLayout { Children = { mainTable, deleteTable } } };
ToolbarItems.Add(saveToolBarItem);
if(Device.OS == TargetPlatform.iOS)
{
diff --git a/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs b/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs
index c49f8afc7..35ad9d460 100644
--- a/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs
+++ b/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs
@@ -39,7 +39,8 @@ namespace Bit.App.Pages
Margin = new Thickness(15, 40, 15, 0),
HorizontalTextAlignment = TextAlignment.Center,
FontFamily = "Courier",
- LineBreakMode = LineBreakMode.TailTruncation
+ LineBreakMode = LineBreakMode.TailTruncation,
+ VerticalOptions = LayoutOptions.Start
};
var tgr = new TapGestureRecognizer();
@@ -64,6 +65,7 @@ namespace Bit.App.Pages
EnableScrolling = false,
Intent = TableIntent.Menu,
HasUnevenRows = true,
+ VerticalOptions = LayoutOptions.End,
Root = new TableRoot
{
new TableSection
diff --git a/src/iOS/AppDelegate.cs b/src/iOS/AppDelegate.cs
index b20e9aea7..6aacf26c4 100644
--- a/src/iOS/AppDelegate.cs
+++ b/src/iOS/AppDelegate.cs
@@ -200,6 +200,7 @@ namespace Bit.iOS
.RegisterType(new ContainerControlledLifetimeManager())
.RegisterType(new ContainerControlledLifetimeManager())
.RegisterType(new ContainerControlledLifetimeManager())
+ .RegisterType(new ContainerControlledLifetimeManager())
// Repositories
.RegisterType(new ContainerControlledLifetimeManager())
.RegisterType(new ContainerControlledLifetimeManager())
diff --git a/src/iOS/Controls/ExtendedTableViewRenderer.cs b/src/iOS/Controls/ExtendedTableViewRenderer.cs
index 33b9a5fd8..1f35bc0b5 100644
--- a/src/iOS/Controls/ExtendedTableViewRenderer.cs
+++ b/src/iOS/Controls/ExtendedTableViewRenderer.cs
@@ -23,9 +23,12 @@ namespace Bit.iOS.Controls
UpdateRowHeight(view);
UpdateEstimatedRowHeight(view);
UpdateSeparatorColor(view);
+
+ Control.SectionFooterHeight = 0.01f;
+ Control.EstimatedSectionFooterHeight = 1f;
+ Control.ContentInset = new UIEdgeInsets(0, 0, -35, 0);
}
}
-
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
diff --git a/src/iOS/Services/ReflectionService.cs b/src/iOS/Services/ReflectionService.cs
new file mode 100644
index 000000000..142721485
--- /dev/null
+++ b/src/iOS/Services/ReflectionService.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Reflection;
+using Bit.App.Abstractions;
+using Bit.App.Controls;
+using Xamarin.Forms;
+
+namespace Bit.iOS.Services
+{
+ public class ReflectionService : IReflectionService
+ {
+ public Func GetVisualElementOnSizeRequest(ExtendedTableView tableView)
+ {
+ var handle = typeof(VisualElement).GetMethod(
+ "OnSizeRequest",
+ BindingFlags.Instance | BindingFlags.NonPublic,
+ null,
+ new Type[] { typeof(double), typeof(double) },
+ null)?.MethodHandle;
+
+ if(!handle.HasValue)
+ {
+ throw new ArgumentNullException("handle could not be found.");
+ }
+
+ var pointer = handle.Value.GetFunctionPointer();
+ if(pointer == null)
+ {
+ throw new ArgumentNullException("pointer could not be found.");
+ }
+
+ return (Func)Activator.CreateInstance(typeof(Func), tableView, pointer);
+ }
+ }
+}
diff --git a/src/iOS/iOS.csproj b/src/iOS/iOS.csproj
index a67c1aada..a24ae40f0 100644
--- a/src/iOS/iOS.csproj
+++ b/src/iOS/iOS.csproj
@@ -115,6 +115,7 @@
+