Skip to content

Commit

Permalink
Merge pull request #13 from muak/fix/iOSBindableLayout
Browse files Browse the repository at this point in the history
fix Android addCell / iOS Scrolling
  • Loading branch information
muak authored Apr 25, 2023
2 parents 4198ad0 + 0cc54eb commit 35d1d6e
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 39 deletions.
1 change: 1 addition & 0 deletions SettingsView/Cells/CellBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ public virtual void Reload()

#elif IOS || MACCATALYST
internal UIKit.UITableViewCell ReusableCell { get; set; }
internal Queue<UIKit.UITableViewCell> ReusableCellQueue { get; } = new Queue<UIKit.UITableViewCell>();
internal UIKit.UITableView TableView { get; set; }
#endif

Expand Down
3 changes: 2 additions & 1 deletion SettingsView/Handlers/CellBase/CellBaseHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ protected void SetUpPropertyChanged(CellBaseView nativeCell)
if (parentElement != null)
{
parentElement.PropertyChanged += nativeCell.ParentPropertyChanged;
var section = parentElement.Model.GetSection(SettingsModel.GetPath(virtualCell).Item1);

var section = parentElement.Model.GetSectionFromCell(virtualCell);
if (section != null)
{
virtualCell.Section = section;
Expand Down
1 change: 1 addition & 0 deletions SettingsView/Platforms/Android/ModelProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ void AddSection(NotifyCollectionChangedEventArgs e)
Cell = cell,
ViewType = (ViewType)ViewTypes[cell.GetType()],
};

this.Insert(i + 1 + startIndex, rowInfo);
}

Expand Down
29 changes: 7 additions & 22 deletions SettingsView/Platforms/iOS/Cells/CellBaseView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,13 @@ internal void UpdateDescriptionText()
if (CellParent.HasUnevenRows)
{
if (CellParent.Handler.PlatformView is AiTableView tv)
{
tv.BeginUpdates();
tv.EndUpdates();
{
// TODO: The following code is needed to dynamically change the cell height
// according to the contents of the Description, but it is commented out
// because it causes scrolling problems.
// The workaround is probably to do it at the timing of PropertyChanged.
//tv.BeginUpdates();
//tv.EndUpdates();
}
}
}
Expand Down Expand Up @@ -542,25 +546,6 @@ public virtual void UpdateCell(UITableView tableView = null)
{
if (TitleLabel is null)
return; // For HotReload

//UpdateBackgroundColor();
//UpdateTitleText();
//UpdateTitleColor();
//UpdateTitleFont();
//UpdateDescriptionText();
//UpdateDescriptionColor();
//UpdateDescriptionFont();
//UpdateHintText();
//UpdateHintTextColor();
//UpdateHintFont();

////UpdateIcon();
//UpdateIconRadius();

//UpdateIsEnabled();
//UpdateIsVisible();

//SetNeedsLayout();
}

/// <summary>
Expand Down
67 changes: 55 additions & 12 deletions SettingsView/Platforms/iOS/Cells/CustomCellContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.InteropServices;
using System.Threading;
using AiForms.Settings.Extensions;
using Microsoft.Maui;
using Microsoft.Maui.Controls;
Expand Down Expand Up @@ -42,6 +43,14 @@ protected override void Dispose(bool disposing)
{
_virtualCell.PropertyChanged -= CellPropertyChanged;
_virtualCell.MeasureInvalidated -= OnMeasureInvalidated;
foreach (var child in CustomCellContent.ElementDescendants(_virtualCell))
{
if (child is Layout layout)
{
layout.SizeChanged -= OnInnerLayoutSizeChanged;
}
child.MeasureInvalidated -= OnMeasureInvalidated;
}
}

CustomCell = null;
Expand Down Expand Up @@ -93,7 +102,7 @@ public virtual void UpdateCell(View newCell, UITableView tableView)
// If oldCell and newCell are the same
if (oldCell == newCell)
{
if (!CustomCell.IsForceLayout)
if (!CustomCell.IsForceLayout && Subviews.Any())
{
// do nothing.
return;
Expand All @@ -104,6 +113,7 @@ public virtual void UpdateCell(View newCell, UITableView tableView)

if (oldCell != null)
{
_cts?.Cancel();
oldCell.PropertyChanged -= CellPropertyChanged;
oldCell.MeasureInvalidated -= OnMeasureInvalidated;
// Delete previous child element
Expand All @@ -114,6 +124,10 @@ public virtual void UpdateCell(View newCell, UITableView tableView)
oldCell.MeasureInvalidated -= OnMeasureInvalidated;
foreach (var child in CustomCellContent.ElementDescendants(oldCell))
{
if (child is Layout layout)
{
layout.SizeChanged -= OnInnerLayoutSizeChanged;
}
child.MeasureInvalidated -= OnMeasureInvalidated;
}
}
Expand Down Expand Up @@ -180,26 +194,47 @@ public virtual void UpdateCell(View newCell, UITableView tableView)

UpdateNativeCell();

SetNeedsLayout();
//SetNeedsLayout();

_virtualCell.MeasureInvalidated += OnMeasureInvalidated;
foreach (var child in CustomCellContent.ElementDescendants(_virtualCell))
{
if(child is Layout layout)
{
// Also detects changes in the size of descendant layout(BindableLayout)
layout.SizeChanged += OnInnerLayoutSizeChanged;
}
// Also detects changes in the size of descendant elements
child.MeasureInvalidated += OnMeasureInvalidated;
}
}

private void OnInnerLayoutSizeChanged(object sender, EventArgs e)
{
LayoutDispacher();
}

private void OnMeasureInvalidated(object sender, EventArgs e)
{
LayoutDispacher();
}

async Task ForceLayout(CancellationToken token)
{
if(_tableView != null)
if(_tableView == null)
{
ForceLayout(_tableView, _virtualCell.Handler as IPlatformViewHandler);
return;
}
var tableView = _tableView;
var handler = _virtualCell.Handler as IPlatformViewHandler;

// Wait a little and execute layout processing only on the last event
await Task.Delay(100);
if (token.IsCancellationRequested)
{
return;
}
}

void ForceLayout(UITableView tableView, IPlatformViewHandler handler)
{
_lastFrameWidth = tableView.Frame.Width;
var height = double.PositiveInfinity;

Expand Down Expand Up @@ -229,7 +264,7 @@ void ForceLayout(UITableView tableView, IPlatformViewHandler handler)
_virtualCell.Arrange(new Rect(0, 0, _lastMeasureWidth, _lastMeasureHeight));

native.SetNeedsUpdateConstraints();
native.UpdateConstraintsIfNeeded();
//native.UpdateConstraintsIfNeeded();
SetNeedsLayout();

tableView.BeginUpdates();
Expand All @@ -248,8 +283,8 @@ void ArrangeSubView(IPlatformViewHandler handler)
_heightConstraint.Active = false;
_heightConstraint.Priority = 1f;
_heightConstraint?.Dispose();
native.SetNeedsUpdateConstraints();
native.UpdateConstraintsIfNeeded();
//native.SetNeedsUpdateConstraints();
//native.UpdateConstraintsIfNeeded();
}

_heightConstraint = native.HeightAnchor.ConstraintEqualTo((NFloat)_lastMeasureHeight);
Expand All @@ -261,8 +296,16 @@ void ArrangeSubView(IPlatformViewHandler handler)
native.BottomAnchor.ConstraintEqualTo(BottomAnchor).Active = true;
native.RightAnchor.ConstraintEqualTo(RightAnchor).Active = true;

native.SetNeedsUpdateConstraints();
native.UpdateConstraintsIfNeeded();
//native.SetNeedsUpdateConstraints();
//native.UpdateConstraintsIfNeeded();
}

CancellationTokenSource _cts = new CancellationTokenSource();
void LayoutDispacher()
{
_cts?.Cancel();
_cts = new CancellationTokenSource();
_ = ForceLayout(_cts.Token);
}

static IEnumerable<VisualElement> ElementDescendants(Element element)
Expand Down
3 changes: 2 additions & 1 deletion SettingsView/Platforms/iOS/Cells/CustomCellView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public CustomCellView(CellBase virtualCell) : base(virtualCell)
public override void UpdateConstraints()
{
base.UpdateConstraints();
LayoutIfNeeded(); // let the layout immediately reflect when update constraints.
// It works fine even if disable this code.
//LayoutIfNeeded(); // let the layout immediately reflect when update constraints.
}

protected override void SetUpContentView()
Expand Down
2 changes: 1 addition & 1 deletion SettingsView/Platforms/iOS/SettingsTableSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public override UITableViewCell GetCell(UITableView tableView, NSIndexPath index
// Because the layer was hidden we need to layout the cell by hand
if (cellWithContent != null)
{
cellWithContent.LayoutSubviews();
//cellWithContent.LayoutSubviews();
}

return platformCell;
Expand Down
2 changes: 1 addition & 1 deletion SettingsView/SettingsModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ internal static Tuple<int, int> GetPath(CellBase item)
}


static void SetPath(CellBase item, Tuple<int, int> index)
internal static void SetPath(CellBase item, Tuple<int, int> index)
{
if (item == null)
return;
Expand Down
2 changes: 1 addition & 1 deletion nuget/AzurePipelines.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ There are various cells such as (LabelCell,ButtonCell,CommandCell,SwitchCell,Che
</description>
<summary></summary>
<releaseNotes>
Add platform MacCatalyst
bug fixes
</releaseNotes>
<tags>MAUI TableView Cell Setting Configuration Option ListView UITableView RecyclerView ReOrder DragDrop</tags>
<language>en-US</language>
Expand Down

0 comments on commit 35d1d6e

Please sign in to comment.