* [Controls] Add repo for #1905 * [iOS] Update refresh control to handle large titles * [iOS] Update refresh control to handle large titles [iOS] Update refresh control to handle large titles [iOS] Delay setting refreshcontrol hidden to true [iOS] Better fix, manually animate Fix animation not showing fix * [iOS] Update refresh control to handle large titles * [iOS] Be safe on UIRefreshcontrol changes * [iOS] Force the Refresh to show when using large titles * [iOS] Just trigger if we really pull to refresh * [iOS] More fixes to refreshcontrol * [iOS] Only force scroll if in Portrait and large titles * Update ListViewRenderer.cs
This commit is contained in:
Родитель
efbadcf401
Коммит
de205114f8
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
|
@ -16,5 +17,24 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static T FindParentOfType<T>(this VisualElement element)
|
||||
{
|
||||
var navPage = element.GetParentsPath()
|
||||
.OfType<T>()
|
||||
.FirstOrDefault();
|
||||
return navPage;
|
||||
}
|
||||
|
||||
internal static IEnumerable<Element> GetParentsPath(this VisualElement self)
|
||||
{
|
||||
Element current = self;
|
||||
|
||||
while (!Application.IsApplicationOrNull(current.RealParent))
|
||||
{
|
||||
current = current.RealParent;
|
||||
yield return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
ITemplatedItemsView<Cell> TemplatedItemsView => Element;
|
||||
public override UIViewController ViewController => _tableViewController;
|
||||
bool _disposed;
|
||||
bool _usingLargeTitles;
|
||||
|
||||
protected UITableViewRowAnimation InsertRowsAnimation { get; set; } = UITableViewRowAnimation.Automatic;
|
||||
protected UITableViewRowAnimation DeleteRowsAnimation { get; set; } = UITableViewRowAnimation.Automatic;
|
||||
|
@ -211,10 +212,13 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
if (Control == null)
|
||||
{
|
||||
_tableViewController = new FormsUITableViewController(e.NewElement);
|
||||
if (Forms.IsiOS11OrNewer)
|
||||
{
|
||||
var parentNav = e.NewElement.FindParentOfType<NavigationPage>();
|
||||
_usingLargeTitles = (parentNav != null && parentNav.OnThisPlatform().PrefersLargeTitles());
|
||||
}
|
||||
_tableViewController = new FormsUITableViewController(e.NewElement, _usingLargeTitles);
|
||||
SetNativeControl(_tableViewController.TableView);
|
||||
if (Forms.IsiOS9OrNewer)
|
||||
Control.CellLayoutMarginsFollowReadableWidth = false;
|
||||
|
||||
_insetTracker = new KeyboardInsetTracker(_tableViewController.TableView, () => Control.Window, insets => Control.ContentInset = Control.ScrollIndicatorInsets = insets, point =>
|
||||
{
|
||||
|
@ -983,10 +987,9 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
throw new NotSupportedException("Header cells do not support context actions");
|
||||
|
||||
var renderer = (CellRenderer)Internals.Registrar.Registered.GetHandlerForObject<IRegisterable>(cell);
|
||||
|
||||
view = new HeaderWrapperView { Cell = cell };
|
||||
view.AddSubview(renderer.GetCell(cell, null, tableView));
|
||||
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -1100,7 +1103,14 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
public override void Scrolled(UIScrollView scrollView)
|
||||
{
|
||||
if (_isDragging && scrollView.ContentOffset.Y < 0)
|
||||
{
|
||||
_uiTableViewController.UpdateShowHideRefresh(true);
|
||||
}
|
||||
|
||||
if (_isDragging && scrollView.ContentOffset.Y < -10f && _uiTableViewController._usingLargeTitles && Device.Info.CurrentOrientation.IsPortrait())
|
||||
{
|
||||
_uiTableViewController.ForceRefreshing();
|
||||
}
|
||||
}
|
||||
|
||||
public override string[] SectionIndexTitles(UITableView tableView)
|
||||
|
@ -1291,12 +1301,17 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
bool _refreshAdded;
|
||||
bool _disposed;
|
||||
internal bool _usingLargeTitles;
|
||||
bool _isRefreshing;
|
||||
|
||||
public FormsUITableViewController(ListView element)
|
||||
public FormsUITableViewController(ListView element, bool usingLargeTitles)
|
||||
{
|
||||
if (Forms.IsiOS9OrNewer)
|
||||
TableView.CellLayoutMarginsFollowReadableWidth = false;
|
||||
_refresh = new UIRefreshControl();
|
||||
|
||||
_usingLargeTitles = usingLargeTitles;
|
||||
|
||||
_refresh = new FormsRefreshControl(_usingLargeTitles);
|
||||
_refresh.ValueChanged += OnRefreshingChanged;
|
||||
_list = element;
|
||||
}
|
||||
|
@ -1315,6 +1330,10 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
_refresh.BeginRefreshing();
|
||||
|
||||
//hack: On iOS11 with large titles we need to adjust the scroll offset manually
|
||||
//since our UITableView is not the first child of the UINavigationController
|
||||
UpdateContentOffset(TableView.ContentOffset.Y - _refresh.Frame.Height);
|
||||
|
||||
//hack: when we don't have cells in our UITableView the spinner fails to appear
|
||||
CheckContentSize();
|
||||
|
||||
|
@ -1323,8 +1342,14 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
}
|
||||
else
|
||||
{
|
||||
if (RefreshControl == null)
|
||||
return;
|
||||
|
||||
_refresh.EndRefreshing();
|
||||
|
||||
UpdateContentOffset(-1);
|
||||
|
||||
_isRefreshing = false;
|
||||
if (!_list.IsPullToRefreshEnabled)
|
||||
RemoveRefresh();
|
||||
}
|
||||
|
@ -1351,6 +1376,19 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
// 5. We end up here; A refresh is in progress while being asked to disable pullToRefresh
|
||||
}
|
||||
|
||||
//hack: Form some reason UIKit isn't allowing to scroll negative values with largetitles
|
||||
public void ForceRefreshing()
|
||||
{
|
||||
if (!_list.IsPullToRefreshEnabled)
|
||||
return;
|
||||
if (!_refresh.Refreshing && !_isRefreshing)
|
||||
{
|
||||
_isRefreshing = true;
|
||||
UpdateContentOffset(TableView.ContentOffset.Y - _refresh.Frame.Height, _refresh.BeginRefreshing);
|
||||
_list.SendRefreshing();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateShowHideRefresh(bool shouldHide)
|
||||
{
|
||||
if (_list.IsPullToRefreshEnabled)
|
||||
|
@ -1407,6 +1445,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
if (_refresh.Refreshing)
|
||||
_list.SendRefreshing();
|
||||
|
||||
_isRefreshing = _refresh.Refreshing;
|
||||
}
|
||||
|
||||
void RemoveRefresh()
|
||||
|
@ -1414,11 +1454,55 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
if (!_refreshAdded)
|
||||
return;
|
||||
|
||||
if (_refresh.Refreshing)
|
||||
if (_refresh.Refreshing || _isRefreshing)
|
||||
_refresh.EndRefreshing();
|
||||
|
||||
RefreshControl = null;
|
||||
_refreshAdded = false;
|
||||
_isRefreshing = false;
|
||||
}
|
||||
|
||||
void UpdateContentOffset(nfloat offset, Action completed = null)
|
||||
{
|
||||
if (!_usingLargeTitles)
|
||||
return;
|
||||
|
||||
UIView.Animate(0.2, () => TableView.ContentOffset = new CoreGraphics.CGPoint(TableView.ContentOffset.X, offset), completed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class FormsRefreshControl : UIRefreshControl
|
||||
{
|
||||
bool _usingLargeTitles;
|
||||
|
||||
public FormsRefreshControl(bool usingLargeTitles)
|
||||
{
|
||||
_usingLargeTitles = usingLargeTitles;
|
||||
}
|
||||
|
||||
public override bool Hidden
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Hidden;
|
||||
}
|
||||
set
|
||||
{
|
||||
//hack: ahahah take that UIKit!
|
||||
//when using pull to refresh with Large tiles sometimes iOS tries to hide the UIRefreshControl
|
||||
if (_usingLargeTitles && value && Refreshing)
|
||||
return;
|
||||
base.Hidden = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void BeginRefreshing()
|
||||
{
|
||||
base.BeginRefreshing();
|
||||
if (!_usingLargeTitles)
|
||||
return;
|
||||
Hidden = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче