зеркало из https://github.com/DeGsoft/maui-linux.git
* crash fixes https://github.com/xamarin/Xamarin.Forms/issues/4388 * Subview Z-index fix * [MacOS] Dispose cleanup * Added WantsLayer prop to Insert method * Added disposing check to ViewRenderer
This commit is contained in:
Родитель
15c6f561e6
Коммит
334e23d7c6
|
@ -115,7 +115,7 @@
|
|||
<Name>Xamarin.Forms.Maps</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Xamarin.Forms.Platform\Xamarin.Forms.Platform.csproj">
|
||||
<Project>{67F9D3A8-F71E-4428-913F-C37AE82CDB24}</Project>
|
||||
<Project>{D31A6537-ED9C-4EBD-B231-A8D4FE44126A}</Project>
|
||||
<Name>Xamarin.Forms.Platform</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Xamarin.Forms.Platform.MacOS\Xamarin.Forms.Platform.MacOS.csproj">
|
||||
|
|
|
@ -41,8 +41,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
IVisualElementRenderer renderer;
|
||||
if (_rendererRef != null && _rendererRef.TryGetTarget(out renderer) && renderer.Element != null)
|
||||
{
|
||||
Platform.DisposeModelAndChildrenRenderers(renderer.Element);
|
||||
|
||||
renderer.Element.DisposeModalAndChildRenderers();
|
||||
_rendererRef = null;
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +98,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
//when cells are getting reused the element could be already set to another cell
|
||||
//so we should dispose based on the renderer and not the renderer.Element
|
||||
Platform.DisposeRendererAndChildren(renderer);
|
||||
renderer.Element.DisposeModalAndChildRenderers();
|
||||
renderer = GetNewRenderer();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
if (disposing)
|
||||
{
|
||||
foreach (var modal in _modals)
|
||||
Platform.DisposeModelAndChildrenRenderers(modal);
|
||||
modal.DisposeModalAndChildRenderers();
|
||||
_renderer = null;
|
||||
}
|
||||
_disposed = true;
|
||||
|
@ -76,7 +76,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
void HandleChildRemoved(object sender, ElementEventArgs e)
|
||||
{
|
||||
var view = e.Element;
|
||||
Platform.DisposeModelAndChildrenRenderers(view);
|
||||
view.DisposeModalAndChildRenderers();
|
||||
}
|
||||
|
||||
Task PresentModalAsync(Page modal, bool animated)
|
||||
|
@ -124,7 +124,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
: NSViewControllerTransitionOptions.None;
|
||||
|
||||
var task = _renderer.HandleAsyncAnimation(controller, toViewController, option,
|
||||
() => Platform.DisposeModelAndChildrenRenderers(modal), modal);
|
||||
() => modal.DisposeModalAndChildRenderers() , modal);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,6 +193,32 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
}
|
||||
}
|
||||
|
||||
internal void UpdateNavigationItems(bool forceShowBackButton = false)
|
||||
{
|
||||
if (_toolbar == null || _navigation == null || _navigationGroup == null)
|
||||
return;
|
||||
var items = new List<ToolbarItem>();
|
||||
if (ShowBackButton(forceShowBackButton))
|
||||
{
|
||||
var backButtonItem = new ToolbarItem
|
||||
{
|
||||
Text = GetPreviousPageTitle(),
|
||||
Command = new Command(async () => await NavigateBackFrombackButton())
|
||||
};
|
||||
items.Add(backButtonItem);
|
||||
}
|
||||
|
||||
UpdateGroup(_navigationGroup, items, BackButtonItemWidth, -1);
|
||||
|
||||
var navItemBack = _navigationGroup.Items.FirstOrDefault();
|
||||
if (navItemBack != null)
|
||||
{
|
||||
navItemBack.Button.Image = NSImage.ImageNamed(NSImageName.GoLeftTemplate);
|
||||
navItemBack.Button.SizeToFit();
|
||||
navItemBack.Button.AccessibilityTitle = "NSBackButton";
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateBarBackgroundColor()
|
||||
{
|
||||
var bgColor = GetBackgroundColor().CGColor;
|
||||
|
@ -223,12 +249,12 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
await popAsyncInner;
|
||||
}
|
||||
|
||||
bool ShowBackButton()
|
||||
bool ShowBackButton(bool forceShowBackButton)
|
||||
{
|
||||
if (_navigation == null)
|
||||
return false;
|
||||
|
||||
return NavigationPage.GetHasBackButton(_navigation.CurrentPage) && !IsRootPage();
|
||||
return NavigationPage.GetHasBackButton(_navigation.CurrentPage) && (forceShowBackButton || !IsRootPage());
|
||||
}
|
||||
|
||||
bool IsRootPage()
|
||||
|
@ -320,32 +346,6 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateGroup(_toolbarGroup, currentPage.ToolbarItems, ToolbarItemWidth, ToolbarItemSpacing);
|
||||
}
|
||||
|
||||
void UpdateNavigationItems()
|
||||
{
|
||||
if (_toolbar == null || _navigation == null || _navigationGroup == null)
|
||||
return;
|
||||
var items = new List<ToolbarItem>();
|
||||
if (ShowBackButton())
|
||||
{
|
||||
var backButtonItem = new ToolbarItem
|
||||
{
|
||||
Text = GetPreviousPageTitle(),
|
||||
Command = new Command(async () => await NavigateBackFrombackButton())
|
||||
};
|
||||
items.Add(backButtonItem);
|
||||
}
|
||||
|
||||
UpdateGroup(_navigationGroup, items, BackButtonItemWidth, -1);
|
||||
|
||||
var navItemBack = _navigationGroup.Items.FirstOrDefault();
|
||||
if (navItemBack != null)
|
||||
{
|
||||
navItemBack.Button.Image = NSImage.ImageNamed(NSImageName.GoLeftTemplate);
|
||||
navItemBack.Button.SizeToFit();
|
||||
navItemBack.Button.AccessibilityTitle = "NSBackButton";
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateTabbedItems()
|
||||
{
|
||||
if (_toolbar == null || _navigation == null || _tabbedGroup == null)
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
view.IsPlatformEnabled = newvalue != null;
|
||||
});
|
||||
|
||||
readonly PlatformRenderer PlatformRenderer;
|
||||
readonly PlatformRenderer _renderer;
|
||||
|
||||
bool _appeared;
|
||||
bool _disposed;
|
||||
|
@ -26,12 +26,12 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
internal Platform()
|
||||
{
|
||||
PlatformRenderer = new PlatformRenderer(this);
|
||||
_renderer = new PlatformRenderer(this);
|
||||
|
||||
MessagingCenter.Subscribe(this, Page.AlertSignalName, (Page sender, AlertArguments arguments) =>
|
||||
{
|
||||
var alert = NSAlert.WithMessage(arguments.Title, arguments.Cancel, arguments.Accept, null, arguments.Message);
|
||||
var result = alert.RunSheetModal(PlatformRenderer.View.Window);
|
||||
var result = alert.RunSheetModal(_renderer.View.Window);
|
||||
if (arguments.Accept == null)
|
||||
arguments.SetResult(result == 1);
|
||||
else
|
||||
|
@ -57,7 +57,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
alert.Layout();
|
||||
}
|
||||
|
||||
var result = (int)alert.RunSheetModal(PlatformRenderer.View.Window);
|
||||
var result = (int)alert.RunSheetModal(_renderer.View.Window);
|
||||
var titleResult = string.Empty;
|
||||
if (result == 1)
|
||||
titleResult = arguments.Cancel;
|
||||
|
@ -102,8 +102,10 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
MessagingCenter.Unsubscribe<Page, AlertArguments>(this, Page.AlertSignalName);
|
||||
MessagingCenter.Unsubscribe<Page, bool>(this, Page.BusySetSignalName);
|
||||
|
||||
DisposeModelAndChildrenRenderers(Page);
|
||||
PlatformRenderer.Dispose();
|
||||
Page.DisposeModalAndChildRenderers();
|
||||
//foreach (var modal in _modals)
|
||||
//modal.DisposeModalAndChildRenderers();
|
||||
_renderer.Dispose();
|
||||
}
|
||||
|
||||
public static IVisualElementRenderer CreateRenderer(VisualElement element)
|
||||
|
@ -130,50 +132,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
base.OnBindingContextChanged();
|
||||
}
|
||||
|
||||
internal NSViewController ViewController => PlatformRenderer;
|
||||
|
||||
internal static void DisposeModelAndChildrenRenderers(Element view)
|
||||
{
|
||||
foreach (VisualElement child in view.Descendants())
|
||||
DisposeRenderer(child);
|
||||
|
||||
DisposeRenderer(view);
|
||||
}
|
||||
|
||||
static void DisposeRenderer(Element view)
|
||||
{
|
||||
IVisualElementRenderer renderer = GetRenderer((VisualElement)view);
|
||||
if (renderer?.ViewController?.ParentViewController != null)
|
||||
renderer?.ViewController?.RemoveFromParentViewController();
|
||||
|
||||
renderer?.NativeView?.RemoveFromSuperview();
|
||||
renderer?.Dispose();
|
||||
|
||||
view.ClearValue(RendererProperty);
|
||||
}
|
||||
|
||||
internal static void DisposeRendererAndChildren(IVisualElementRenderer rendererToRemove)
|
||||
{
|
||||
if (rendererToRemove == null || rendererToRemove.Element == null)
|
||||
return;
|
||||
|
||||
if (GetRenderer(rendererToRemove.Element) == rendererToRemove)
|
||||
rendererToRemove.Element.ClearValue(RendererProperty);
|
||||
|
||||
if (rendererToRemove.NativeView != null)
|
||||
{
|
||||
var subviews = rendererToRemove.NativeView.Subviews;
|
||||
for (var i = 0; i < subviews.Length; i++)
|
||||
{
|
||||
var childRenderer = subviews[i] as IVisualElementRenderer;
|
||||
if (childRenderer != null)
|
||||
DisposeRendererAndChildren(childRenderer);
|
||||
}
|
||||
|
||||
rendererToRemove.NativeView.RemoveFromSuperview();
|
||||
}
|
||||
rendererToRemove.Dispose();
|
||||
}
|
||||
internal NSViewController ViewController => _renderer;
|
||||
|
||||
internal void LayoutSubviews()
|
||||
{
|
||||
|
@ -185,7 +144,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
if (rootRenderer == null)
|
||||
return;
|
||||
|
||||
rootRenderer.SetElementSize(new Size(PlatformRenderer.View.Bounds.Width, PlatformRenderer.View.Bounds.Height));
|
||||
rootRenderer.SetElementSize(new Size(_renderer.View.Bounds.Width, _renderer.View.Bounds.Height));
|
||||
}
|
||||
|
||||
internal void SetPage(Page newRoot)
|
||||
|
@ -203,14 +162,14 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
Page.DescendantRemoved += HandleChildRemoved;
|
||||
|
||||
TargetApplication.NavigationProxy.Inner = PlatformRenderer.Navigation;
|
||||
TargetApplication.NavigationProxy.Inner = _renderer.Navigation;
|
||||
}
|
||||
|
||||
internal void DidAppear()
|
||||
{
|
||||
PlatformRenderer.Navigation.AnimateModalPages = false;
|
||||
TargetApplication.NavigationProxy.Inner = PlatformRenderer.Navigation;
|
||||
PlatformRenderer.Navigation.AnimateModalPages = true;
|
||||
_renderer.Navigation.AnimateModalPages = false;
|
||||
TargetApplication.NavigationProxy.Inner = _renderer.Navigation;
|
||||
_renderer.Navigation.AnimateModalPages = true;
|
||||
}
|
||||
|
||||
internal void WillAppear()
|
||||
|
@ -259,10 +218,10 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
var viewRenderer = CreateRenderer(view);
|
||||
SetRenderer(view, viewRenderer);
|
||||
|
||||
PlatformRenderer.View.AddSubview(viewRenderer.NativeView);
|
||||
_renderer.View.AddSubview(viewRenderer.NativeView);
|
||||
if (viewRenderer.ViewController != null)
|
||||
PlatformRenderer.AddChildViewController(viewRenderer.ViewController);
|
||||
viewRenderer.SetElementSize(new Size(PlatformRenderer.View.Bounds.Width, PlatformRenderer.View.Bounds.Height));
|
||||
_renderer.AddChildViewController(viewRenderer.ViewController);
|
||||
viewRenderer.SetElementSize(new Size(_renderer.View.Bounds.Width, _renderer.View.Bounds.Height));
|
||||
}
|
||||
else
|
||||
Console.Error.WriteLine("A Renderer was already found, potential view double add");
|
||||
|
@ -271,7 +230,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
void HandleChildRemoved(object sender, ElementEventArgs e)
|
||||
{
|
||||
var view = e.Element;
|
||||
DisposeModelAndChildrenRenderers(view);
|
||||
view.DisposeModalAndChildRenderers();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,13 +38,17 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_platformNavigation.Dispose();
|
||||
_platformNavigation = null;
|
||||
Platform = null;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
static int s_sectionCount;
|
||||
readonly nfloat _defaultSectionHeight;
|
||||
readonly Dictionary<DataTemplate, int> _templateToId = new Dictionary<DataTemplate, int>();
|
||||
readonly NSTableView _nsTableView;
|
||||
protected readonly ListView List;
|
||||
NSTableView _nsTableView;
|
||||
ListView List;
|
||||
bool _disposed;
|
||||
|
||||
ITemplatedItemsView<Cell> TemplatedItemsView => List;
|
||||
|
||||
|
@ -185,6 +186,26 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
return nativeCell;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (List != null)
|
||||
{
|
||||
List.ItemSelected -= OnItemSelected;
|
||||
List = null;
|
||||
}
|
||||
_nsTableView = null;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected virtual Cell GetCellForPath(NSIndexPath indexPath, bool isGroupHeader)
|
||||
{
|
||||
var templatedItems = TemplatedItemsView.TemplatedItems;
|
||||
|
|
|
@ -40,23 +40,13 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && !_disposed)
|
||||
{
|
||||
_disposed = true;
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
var viewsToLookAt = new Stack<NSView>(Subviews);
|
||||
while (viewsToLookAt.Count > 0)
|
||||
if (disposing)
|
||||
{
|
||||
var view = viewsToLookAt.Pop();
|
||||
var viewCellRenderer = view as ViewCellNSView;
|
||||
if (viewCellRenderer != null)
|
||||
viewCellRenderer.Dispose();
|
||||
else
|
||||
{
|
||||
foreach (var child in view.Subviews)
|
||||
viewsToLookAt.Push(child);
|
||||
}
|
||||
}
|
||||
foreach (NSView subview in Subviews)
|
||||
DisposeSubviews(subview);
|
||||
|
||||
if (Element != null)
|
||||
{
|
||||
|
@ -64,21 +54,53 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
templatedItems.CollectionChanged -= OnCollectionChanged;
|
||||
templatedItems.GroupedCollectionChanged -= OnGroupedCollectionChanged;
|
||||
}
|
||||
|
||||
if (_dataSource != null)
|
||||
{
|
||||
_dataSource.Dispose();
|
||||
_dataSource = null;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
if (_headerRenderer != null)
|
||||
{
|
||||
ClearHeader();
|
||||
_headerRenderer.Element?.DisposeModalAndChildRenderers();
|
||||
_headerRenderer = null;
|
||||
}
|
||||
if (_footerRenderer != null)
|
||||
{
|
||||
Platform.DisposeModelAndChildrenRenderers(_footerRenderer.Element);
|
||||
_footerRenderer.Element?.DisposeModalAndChildRenderers();
|
||||
_footerRenderer = null;
|
||||
}
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
void DisposeSubviews(NSView view)
|
||||
{
|
||||
var ver = view as IVisualElementRenderer;
|
||||
|
||||
if (ver == null)
|
||||
{
|
||||
// VisualElementRenderers should implement their own dispose methods that will appropriately dispose and remove their child views.
|
||||
// Attempting to do this work twice could cause a SIGSEGV (only observed in iOS8), so don't do this work here.
|
||||
// Non-renderer views, such as separator lines, etc., can be removed here.
|
||||
|
||||
if (view is NSClipView)
|
||||
return;
|
||||
|
||||
foreach (NSView subView in view.Subviews)
|
||||
DisposeSubviews(subView);
|
||||
|
||||
view.RemoveFromSuperview();
|
||||
}
|
||||
|
||||
view.Dispose();
|
||||
}
|
||||
|
||||
protected override void SetBackgroundColor(Color color)
|
||||
{
|
||||
base.SetBackgroundColor(color);
|
||||
|
@ -229,7 +251,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
_table.HeaderView = null;
|
||||
if (_headerRenderer == null)
|
||||
return;
|
||||
Platform.DisposeModelAndChildrenRenderers(_headerRenderer.Element);
|
||||
_headerRenderer.Element.DisposeModalAndChildRenderers();
|
||||
_headerRenderer = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,9 +88,21 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
if (Element != null)
|
||||
{
|
||||
NavigationPage?.SendDisappearing();
|
||||
if (NavigationPage != null)
|
||||
{
|
||||
NavigationPage.PushRequested -= OnPushRequested;
|
||||
NavigationPage.PopRequested -= OnPopRequested;
|
||||
NavigationPage.PopToRootRequested -= OnPopToRootRequested;
|
||||
NavigationPage.RemovePageRequested -= OnRemovedPageRequested;
|
||||
NavigationPage.InsertPageBeforeRequested -= OnInsertPageBeforeRequested;
|
||||
NavigationPage.Popped -= OnPopped;
|
||||
NavigationPage.PoppedToRoot -= OnPoppedToRoot;
|
||||
|
||||
NavigationPage.SendDisappearing();
|
||||
}
|
||||
((Element as IPageContainer<Page>)?.CurrentPage as Page)?.SendDisappearing();
|
||||
Element.PropertyChanged -= OnElementPropertyChanged;
|
||||
Platform.SetRenderer(Element, null);
|
||||
Element = null;
|
||||
}
|
||||
|
||||
|
@ -100,7 +112,19 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
_events?.Dispose();
|
||||
_events = null;
|
||||
|
||||
if(_currentStack != null)
|
||||
{
|
||||
foreach (var childPageWrapper in _currentStack)
|
||||
{
|
||||
childPageWrapper.Dispose();
|
||||
}
|
||||
_currentStack.Clear();
|
||||
_currentStack = null;
|
||||
}
|
||||
|
||||
Platform.NativeToolbarTracker.Navigation = null;
|
||||
_disposed = true;
|
||||
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
@ -175,22 +199,19 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
{
|
||||
ConfigurePageRenderer();
|
||||
|
||||
var navPage = (NavigationPage)Element;
|
||||
|
||||
if (navPage.CurrentPage == null)
|
||||
if (NavigationPage.CurrentPage == null)
|
||||
throw new InvalidOperationException(
|
||||
"NavigationPage must have a root Page before being used. Either call PushAsync with a valid Page, or pass a Page to the constructor before usage.");
|
||||
|
||||
Platform.NativeToolbarTracker.Navigation = navPage;
|
||||
Platform.NativeToolbarTracker.Navigation = NavigationPage;
|
||||
|
||||
NavigationPage.PushRequested += OnPushRequested;
|
||||
NavigationPage.PopRequested += OnPopRequested;
|
||||
NavigationPage.PopToRootRequested += OnPopToRootRequested;
|
||||
NavigationPage.RemovePageRequested += OnRemovedPageRequested;
|
||||
NavigationPage.InsertPageBeforeRequested += OnInsertPageBeforeRequested;
|
||||
|
||||
navPage.Popped += (sender, e) => Platform.NativeToolbarTracker.UpdateToolBar();
|
||||
navPage.PoppedToRoot += (sender, e) => Platform.NativeToolbarTracker.UpdateToolBar();
|
||||
NavigationPage.Popped += OnPopped;
|
||||
NavigationPage.PoppedToRoot += OnPoppedToRoot;
|
||||
|
||||
UpdateBarBackgroundColor();
|
||||
UpdateBarTextColor();
|
||||
|
@ -199,7 +220,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
_events.LoadEvents(NativeView);
|
||||
_tracker = new VisualElementTracker(this);
|
||||
|
||||
navPage.Pages.ForEach(async p => await PushPageAsync(p, false));
|
||||
NavigationPage.Pages.ForEach(async p => await PushPageAsync(p, false));
|
||||
|
||||
UpdateBackgroundColor();
|
||||
}
|
||||
|
@ -213,6 +234,16 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
return pageRenderer;
|
||||
}
|
||||
|
||||
void OnPopped(object sender, NavigationEventArgs e)
|
||||
{
|
||||
Platform.NativeToolbarTracker.UpdateToolBar();
|
||||
}
|
||||
|
||||
void OnPoppedToRoot(object sender, NavigationEventArgs e)
|
||||
{
|
||||
Platform.NativeToolbarTracker.UpdateToolBar();
|
||||
}
|
||||
|
||||
void InsertPageBefore(Page page, Page before)
|
||||
{
|
||||
if (before == null)
|
||||
|
@ -229,17 +260,19 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
var vc = CreateViewControllerForPage(page);
|
||||
vc.SetElementSize(new Size(View.Bounds.Width, View.Bounds.Height));
|
||||
page.Layout(new Rectangle(0, 0, View.Bounds.Width, View.Frame.Height));
|
||||
vc.NativeView.WantsLayer = true;
|
||||
|
||||
var beforeViewController = Platform.GetRenderer(before).ViewController;
|
||||
var beforeControllerIndex = ChildViewControllers.IndexOf(beforeViewController);
|
||||
var beforeRenderer = Platform.GetRenderer(before);
|
||||
var beforeControllerIndex = ChildViewControllers.IndexOf(beforeRenderer.ViewController);
|
||||
|
||||
InsertChildViewController(vc.ViewController, beforeControllerIndex);
|
||||
View.AddSubview(vc.NativeView);
|
||||
View.AddSubview(vc.NativeView, NSWindowOrderingMode.Below, beforeRenderer.NativeView);
|
||||
}
|
||||
|
||||
void OnInsertPageBeforeRequested(object sender, NavigationRequestedEventArgs e)
|
||||
{
|
||||
InsertPageBefore(e.Page, e.BeforePage);
|
||||
Platform.NativeToolbarTracker.UpdateNavigationItems(true);
|
||||
}
|
||||
|
||||
void OnPopRequested(object sender, NavigationRequestedEventArgs e)
|
||||
|
@ -325,11 +358,11 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
if (animated)
|
||||
{
|
||||
var previousPageRenderer = Platform.GetRenderer(previousPage);
|
||||
var previousPageRenderer = CreateViewControllerForPage(previousPage);
|
||||
var transitionStyle = NavigationPage.OnThisPlatform().GetNavigationTransitionPopStyle();
|
||||
|
||||
return await this.HandleAsyncAnimation(target.ViewController, previousPageRenderer.ViewController,
|
||||
ToViewControllerTransitionOptions(transitionStyle), () => Platform.DisposeRendererAndChildren(target), true);
|
||||
ToViewControllerTransitionOptions(transitionStyle), () => target.DisposeRendererAndChildren(), true);
|
||||
}
|
||||
|
||||
RemovePage(page, false);
|
||||
|
|
|
@ -11,8 +11,9 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
const string HeaderIdentifier = nameof(TextCell);
|
||||
const string ItemIdentifier = nameof(ViewCell);
|
||||
|
||||
readonly NSTableView _nsTableView;
|
||||
readonly TableView _tableView;
|
||||
NSTableView _nsTableView;
|
||||
TableView _tableView;
|
||||
bool _disposed;
|
||||
|
||||
public TableViewDataSource(TableViewRenderer tableViewRenderer)
|
||||
{
|
||||
|
@ -39,7 +40,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
var cell = _tableView.Model.GetCell(sectionIndex, itemIndexInSection);
|
||||
_tableView.Model.RowSelected(cell);
|
||||
if (AutomaticallyDeselect)
|
||||
_nsTableView.DeselectRow(row);
|
||||
_nsTableView?.DeselectRow(row);
|
||||
}
|
||||
|
||||
public override nint GetRowCount(NSTableView tableView)
|
||||
|
@ -91,6 +92,20 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
return nativeCell;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing)
|
||||
{
|
||||
if(!_disposed)
|
||||
{
|
||||
_nsTableView = null;
|
||||
_tableView = null;
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
void GetComputedIndexes(nint row, out int sectionIndex, out int itemIndexInSection, out bool isHeader)
|
||||
{
|
||||
var totalItems = 0;
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
public class TableViewRenderer : ViewRenderer<TableView, NSView>
|
||||
{
|
||||
const int DefaultRowHeight = 44;
|
||||
bool _disposed;
|
||||
|
||||
internal NSTableView TableView { get; set; }
|
||||
|
||||
|
@ -17,15 +18,19 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
var viewsToLookAt = new Stack<NSView>(Subviews);
|
||||
while (viewsToLookAt.Count > 0)
|
||||
{
|
||||
var view = viewsToLookAt.Pop();
|
||||
var viewCellRenderer = view as IVisualElementRenderer;
|
||||
var viewCellRenderer = view as ViewCellNSView;
|
||||
if (viewCellRenderer != null)
|
||||
{
|
||||
viewCellRenderer.RemoveFromSuperview();
|
||||
viewCellRenderer.Dispose();
|
||||
}
|
||||
else
|
||||
|
@ -35,6 +40,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
}
|
||||
}
|
||||
}
|
||||
_disposed = true;
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
|
|
@ -237,10 +237,13 @@
|
|||
<Link>VisualElementRenderer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Extensions\NSMenuExtensions.cs" />
|
||||
<Compile Include="..\Xamarin.Forms.Platform.iOS\DisposeHelpers.cs">
|
||||
<Link>DisposeHelpers.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Xamarin.Forms.Platform\Xamarin.Forms.Platform.csproj">
|
||||
<Project>{67F9D3A8-F71E-4428-913F-C37AE82CDB24}</Project>
|
||||
<Project>{D31A6537-ED9C-4EBD-B231-A8D4FE44126A}</Project>
|
||||
<Name>Xamarin.Forms.Platform</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Xamarin.Forms.Core\Xamarin.Forms.Core.csproj">
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#if __MOBILE__
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
#else
|
||||
|
||||
namespace Xamarin.Forms.Platform.MacOS
|
||||
#endif
|
||||
{
|
||||
internal static class DisposeHelpers
|
||||
{
|
||||
|
@ -27,9 +32,11 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
if (renderer.ViewController != null)
|
||||
{
|
||||
#if __MOBILE__
|
||||
var modalWrapper = renderer.ViewController.ParentViewController as ModalWrapper;
|
||||
if (modalWrapper != null)
|
||||
modalWrapper.Dispose();
|
||||
#endif
|
||||
}
|
||||
|
||||
renderer.NativeView.RemoveFromSuperview();
|
||||
|
@ -47,14 +54,16 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
if (rendererToRemove.Element != null && Platform.GetRenderer(rendererToRemove.Element) == rendererToRemove)
|
||||
rendererToRemove.Element.ClearValue(Platform.RendererProperty);
|
||||
|
||||
if (rendererToRemove.NativeView != null)
|
||||
{
|
||||
var subviews = rendererToRemove.NativeView.Subviews;
|
||||
for (var i = 0; i < subviews.Length; i++)
|
||||
{
|
||||
if (subviews[i] is IVisualElementRenderer childRenderer)
|
||||
DisposeRendererAndChildren(childRenderer);
|
||||
}
|
||||
|
||||
rendererToRemove.NativeView.RemoveFromSuperview();
|
||||
}
|
||||
rendererToRemove.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,9 +107,13 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (disposing)
|
||||
{
|
||||
_elementPropertyChanged = null;
|
||||
_controlChanging = null;
|
||||
_controlChanged = null;
|
||||
|
||||
if (disposing && Control != null && ManageNativeControlLifetime)
|
||||
if (Control != null && ManageNativeControlLifetime)
|
||||
{
|
||||
Control.RemoveFromSuperview();
|
||||
Control.Dispose();
|
||||
|
@ -117,6 +121,9 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
}
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<TView> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
|
Загрузка…
Ссылка в новой задаче