Skip to content

Commit

Permalink
Merge pull request #16 from muak/fix/headerview
Browse files Browse the repository at this point in the history
Fix iOS Header/FooterView Recycle
  • Loading branch information
muak committed Sep 5, 2023
2 parents fd9bb22 + 5d2853a commit 21089e6
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 36 deletions.
1 change: 1 addition & 0 deletions Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public static MauiApp CreateMauiApp()
containerRegistry.RegisterForNavigation<MyNavigationPage>();
containerRegistry.RegisterForNavigation<MainPage, MainViewModel>();
containerRegistry.RegisterForNavigation<ContentPage>();
containerRegistry.RegisterForNavigation<ListPage, ListViewModel>();
})
.OnAppStart(navigationService =>
{
Expand Down
4 changes: 2 additions & 2 deletions Sample/Platforms/Android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="jp.kamusoft.settingsview" android:versionCode="1" android:versionName="1.0">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true" android:label="Sample"></application>
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true" android:label="Sample"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="27" android:targetSdkVersion="31" />
<uses-sdk android:minSdkVersion="27" android:targetSdkVersion="33" />
</manifest>
1 change: 1 addition & 0 deletions Sample/Resources/Images/ic_close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions Sample/Sample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
<CodesignKey>Mac Developer</CodesignKey>
<PackageSigningKey>3rd Party Mac Developer Installer</PackageSigningKey>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-android|AnyCPU'">
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
Expand All @@ -70,6 +73,7 @@
<None Remove="Views\Cells\" />
<None Remove="Resources\.DS_Store" />
<None Remove="AiForms.Maui.SettingsView" />
<None Remove="Resources\Images\ic_close.svg" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Prism.DryIoc.Maui" Version="8.1.273-pre" />
Expand Down Expand Up @@ -101,4 +105,7 @@
<ItemGroup>
<ProjectReference Include="..\SettingsView\SettingsView.csproj" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\Images\ic_close.svg" />
</ItemGroup>
</Project>
21 changes: 21 additions & 0 deletions Sample/ViewModels/ListViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.ObjectModel;

namespace Sample.ViewModels;

public class ListViewModel: BindableBase
{
public ObservableCollection<string> ItemsSource { get; set; }

public ListViewModel()
{
var list = new List<string>
{
"Item1","Item2","Item3","Item4","Item5","Item6","Item7","Item8","Item9","Item10",
"Item11","Item12","Item13","Item14","Item15","Item16","Item17","Item18","Item19","Item20",
};

ItemsSource = new ObservableCollection<string>(list);
}
}

4 changes: 2 additions & 2 deletions Sample/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public MainViewModel(INavigationService navigationService)

ToProfileCommand.Subscribe(async _ => {
Description.Value += "01234567890";
//await navigationService.NavigateAsync("ContentPage");
//Description.Value += "01234567890";
await navigationService.NavigateAsync("ListPage");
});

AddContentCommand.Subscribe(_ =>
Expand Down
30 changes: 30 additions & 0 deletions Sample/Views/ListPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sv="clr-namespace:AiForms.Settings;assembly=SettingsView"
x:Class="Sample.Views.ListPage"
Title="ListPage">

<sv:SettingsView ItemsSource="{Binding ItemsSource}">
<sv:SettingsView.ItemTemplate>
<DataTemplate>
<sv:Section>
<sv:Section.HeaderView>
<Grid>
<!--TODO:Image修正-->
<ImageButton Source="ic_close"
WidthRequest="30" HeightRequest="30"
VerticalOptions="Center" HorizontalOptions="End"
Padding="0" />
</Grid>
</sv:Section.HeaderView>

<sv:LabelCell Title="{Binding}" />
</sv:Section>
</DataTemplate>
</sv:SettingsView.ItemTemplate>

</sv:SettingsView>

</ContentPage>
9 changes: 9 additions & 0 deletions Sample/Views/ListPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Sample.Views;

public partial class ListPage : ContentPage
{
public ListPage()
{
InitializeComponent();
}
}
2 changes: 1 addition & 1 deletion SettingsView/Platforms/iOS/Cells/CustomCellContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public virtual void UpdateCell(View newCell, UITableView tableView)
{
subView.RemoveFromSuperview();
}
oldCell.MeasureInvalidated -= OnMeasureInvalidated;

foreach (var child in CustomCellContent.ElementDescendants(oldCell))
{
if (child is Layout layout)
Expand Down
72 changes: 41 additions & 31 deletions SettingsView/Platforms/iOS/CustomHeaderFooterView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ protected internal CustomFooterView(NativeHandle handle) : base(handle)

public class CustomHeaderFooterView:UITableViewHeaderFooterView
{
WeakReference<IPlatformViewHandler> _handlerRef;
bool _disposed;
NSLayoutConstraint _heightConstraint;
View _virtualCell;
Expand Down Expand Up @@ -109,17 +108,12 @@ protected override void Dispose(bool disposing)
{
_virtualCell.PropertyChanged -= CellPropertyChanged;
_virtualCell.MeasureInvalidated -= OnMeasureInvalidated;
_virtualCell.DisposeModalAndChildHandlers();
}

_heightConstraint?.Dispose();
_heightConstraint = null;

IPlatformViewHandler handler;
if (_handlerRef != null && _handlerRef.TryGetTarget(out handler) && handler.VirtualView != null)
{
handler.VirtualView.DisposeModalAndChildHandlers();
_handlerRef = null;
}

_virtualCell = null;
}

Expand All @@ -146,9 +140,9 @@ protected virtual void UpdateIsEnabled()
UserInteractionEnabled = _virtualCell.IsEnabled;
}

public virtual void UpdateCell(View cell,UITableView tableView)
public virtual void UpdateCell(View newCell,UITableView tableView)
{
if(_virtualCell == cell)
if (_virtualCell == newCell)
{
return;
}
Expand All @@ -160,37 +154,54 @@ public virtual void UpdateCell(View cell,UITableView tableView)
oldCell.Handler?.DisconnectHandler();
oldCell.PropertyChanged -= CellPropertyChanged;
oldCell.MeasureInvalidated -= OnMeasureInvalidated;
// Delete previous child element
foreach (var subView in ContentView.Subviews)
{
subView.RemoveFromSuperview();
}
}

_virtualCell = cell;
_virtualCell = newCell;
_virtualCell.PropertyChanged += CellPropertyChanged;

IPlatformViewHandler handler;
if (_handlerRef == null || !_handlerRef.TryGetTarget(out handler))
if (newCell.Handler != null)
{
handler = GetNewHandler();
// TODO:
// Currently, the performance is not good because the number of
// NativieView is kept as many as the number of Cells. To improve this,
// it is necessary to virtualize the Content part of CustomCell as well.
// This can probably be achieved by replacing the Handler and
// resetting the VirtualView.

// If it has already been generated, use it as is.
handler = newCell.Handler as IPlatformViewHandler;
// If the incoming Cell belongs to another parent, peel it off.
handler.PlatformView?.RemoveFromSuperview();
}
else
{
var viewHandlerType = _mauiContext.Handlers.GetHandlerType(_virtualCell.GetType());
var reflectableType = handler as System.Reflection.IReflectableType;
var handlerType = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : (handler != null ? handler.GetType() : typeof(System.Object));
// If Handler is not generated, generate it.
handler = GetNewHandler();
}

if (handlerType == viewHandlerType)
{
handler.SetVirtualView(this._virtualCell);
}
else
{
//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
handler.DisposeHandlersAndChildren();
handler = GetNewHandler();
}
var viewHandlerType = _mauiContext.Handlers.GetHandlerType(_virtualCell.GetType());
var reflectableType = handler as System.Reflection.IReflectableType;
var handlerType = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : (handler != null ? handler.GetType() : typeof(System.Object));

if (handlerType == viewHandlerType)
{
handler.SetVirtualView(_virtualCell);
}
else
{
//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
handler.DisposeHandlersAndChildren();
handler = GetNewHandler();
}

_virtualCell.MeasureInvalidated += OnMeasureInvalidated;

_virtualCell.MeasureInvalidated += OnMeasureInvalidated;

var height = double.PositiveInfinity;
var result = handler.VirtualView.Measure(tableView.Frame.Width, height);
Expand Down Expand Up @@ -232,7 +243,6 @@ protected virtual IPlatformViewHandler GetNewHandler()
}

var newHandler = _virtualCell.ToHandler(_virtualCell.FindMauiContext());
_handlerRef = new WeakReference<IPlatformViewHandler>(newHandler);
ContentView.AddSubview(newHandler.PlatformView);

var native = newHandler.PlatformView;
Expand Down

0 comments on commit 21089e6

Please sign in to comment.