From d8d9c5795f0512467992c8ed25c004d8c4402186 Mon Sep 17 00:00:00 2001 From: Tyler Stegmaier Date: Fri, 12 Mar 2021 00:14:20 -0600 Subject: [PATCH] more progress. Sould fix https://github.com/muak/AiForms.SettingsView/issues/118 --- .../BaseCell/BaseAiDescriptionCell.cs | 1 + .../BaseCell/BaseAiTitledCell.cs | 1 + .../BaseCell/BaseAiValueCell.cs | 1 + .../BaseCell/BaseValueCell.cs | 1 + .../Controls/{ => Core}/BaseTextView.cs | 5 +- .../Controls/{ => Core}/DescriptionView.cs | 2 +- .../Controls/{ => Core}/HintView.cs | 2 +- .../Controls/{ => Core}/TitleView.cs | 2 +- .../Controls/{ => Core}/ValueView.cs | 3 +- .../{ => Controls}/HeaderFooterContainer.cs | 33 ++- .../Jakar.SettingsView.Droid.csproj | 13 +- .../SettingsViewRecyclerAdapter.cs | 1 + src/SettingsView.Droid/ViewHolders.cs | 1 + .../BaseCell/BaseAiDescriptionCell.cs | 1 + .../BaseCell/BaseAiTitledCell.cs | 1 + .../BaseCell/BaseAiValueCell.cs | 1 + src/SettingsView.iOS/BaseCell/BaseCellView.cs | 2 +- .../BaseCell/BasePickerCell.cs | 4 +- .../BaseCell/BaseValueCell.cs | 1 + .../BaseCell/CellBaseRenderer.cs | 86 +++---- .../AccessoryCells/CheckboxCellRenderer.cs | 4 +- .../AccessoryCells/SwitchCellRenderer.cs | 4 +- .../Cells/CommandCells/ButtonCellRenderer.cs | 6 +- .../Cells/CommandCells/CommandCellRenderer.cs | 6 +- .../Cells/EntryCellRenderer.cs | 4 +- .../Cells/Pickers/DatePickerCellRenderer.cs | 5 +- .../Cells/Pickers/NumberPickerCell.cs | 5 +- .../Cells/Pickers/PickerCellRenderer.cs | 4 +- .../Cells/Pickers/TimePickerCellRenderer.cs | 4 +- src/SettingsView.iOS/Controls/AiEditText.cs | 2 +- .../Controls/{ => Core}/BaseTextView.cs | 3 +- .../Controls/{ => Core}/DescriptionView.cs | 3 +- .../Controls/{ => Core}/HintView.cs | 3 +- .../Controls/{ => Core}/TitleView.cs | 4 +- .../Controls/{ => Core}/ValueView.cs | 3 +- .../{OLD_Cells => Controls}/NoCaretField.cs | 2 +- .../CustomHeaderFooterView.cs | 233 ++++++++++++------ .../Extensions/NumberExtensions.cs | 8 + src/SettingsView.iOS/ImageCacheController.cs | 2 +- .../Interfaces/IEntryCellRenderer.cs | 2 +- .../Jakar.SettingsView.iOS.csproj | 26 +- src/SettingsView.iOS/SettingsTableSource.cs | 111 ++++----- src/SettingsView.iOS/SettingsViewRenderer.cs | 43 ++-- src/SettingsView/sv/SettingsModel.cs | 14 +- 44 files changed, 361 insertions(+), 302 deletions(-) rename src/SettingsView.Droid/Controls/{ => Core}/BaseTextView.cs (95%) rename src/SettingsView.Droid/Controls/{ => Core}/DescriptionView.cs (98%) rename src/SettingsView.Droid/Controls/{ => Core}/HintView.cs (98%) rename src/SettingsView.Droid/Controls/{ => Core}/TitleView.cs (98%) rename src/SettingsView.Droid/Controls/{ => Core}/ValueView.cs (97%) rename src/SettingsView.Droid/{ => Controls}/HeaderFooterContainer.cs (88%) rename src/SettingsView.iOS/Controls/{ => Core}/BaseTextView.cs (96%) rename src/SettingsView.iOS/Controls/{ => Core}/DescriptionView.cs (96%) rename src/SettingsView.iOS/Controls/{ => Core}/HintView.cs (96%) rename src/SettingsView.iOS/Controls/{ => Core}/TitleView.cs (95%) rename src/SettingsView.iOS/Controls/{ => Core}/ValueView.cs (96%) rename src/SettingsView.iOS/{OLD_Cells => Controls}/NoCaretField.cs (88%) diff --git a/src/SettingsView.Droid/BaseCell/BaseAiDescriptionCell.cs b/src/SettingsView.Droid/BaseCell/BaseAiDescriptionCell.cs index 1565c6a..109986f 100644 --- a/src/SettingsView.Droid/BaseCell/BaseAiDescriptionCell.cs +++ b/src/SettingsView.Droid/BaseCell/BaseAiDescriptionCell.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using Android.Runtime; using Jakar.SettingsView.Droid.Controls; +using Jakar.SettingsView.Droid.Controls.Core; using Xamarin.Forms; using AContext = Android.Content.Context; diff --git a/src/SettingsView.Droid/BaseCell/BaseAiTitledCell.cs b/src/SettingsView.Droid/BaseCell/BaseAiTitledCell.cs index 93f8479..04caeff 100644 --- a/src/SettingsView.Droid/BaseCell/BaseAiTitledCell.cs +++ b/src/SettingsView.Droid/BaseCell/BaseAiTitledCell.cs @@ -3,6 +3,7 @@ using Android.Runtime; using Android.Widget; using Jakar.SettingsView.Droid.Controls; +using Jakar.SettingsView.Droid.Controls.Core; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; using AContext = Android.Content.Context; diff --git a/src/SettingsView.Droid/BaseCell/BaseAiValueCell.cs b/src/SettingsView.Droid/BaseCell/BaseAiValueCell.cs index aeb6ee9..6fa6819 100644 --- a/src/SettingsView.Droid/BaseCell/BaseAiValueCell.cs +++ b/src/SettingsView.Droid/BaseCell/BaseAiValueCell.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using Android.Runtime; using Jakar.SettingsView.Droid.Controls; +using Jakar.SettingsView.Droid.Controls.Core; using Xamarin.Forms; using AContext = Android.Content.Context; diff --git a/src/SettingsView.Droid/BaseCell/BaseValueCell.cs b/src/SettingsView.Droid/BaseCell/BaseValueCell.cs index 0d53952..66e5a6c 100644 --- a/src/SettingsView.Droid/BaseCell/BaseValueCell.cs +++ b/src/SettingsView.Droid/BaseCell/BaseValueCell.cs @@ -4,6 +4,7 @@ using Android.Views; using Android.Widget; using Jakar.SettingsView.Droid.Controls; +using Jakar.SettingsView.Droid.Controls.Core; using Jakar.SettingsView.Droid.Extensions; using Jakar.SettingsView.Shared; using Jakar.SettingsView.Shared.Misc; diff --git a/src/SettingsView.Droid/Controls/BaseTextView.cs b/src/SettingsView.Droid/Controls/Core/BaseTextView.cs similarity index 95% rename from src/SettingsView.Droid/Controls/BaseTextView.cs rename to src/SettingsView.Droid/Controls/Core/BaseTextView.cs index 6cd6aef..e8f27a7 100644 --- a/src/SettingsView.Droid/Controls/BaseTextView.cs +++ b/src/SettingsView.Droid/Controls/Core/BaseTextView.cs @@ -3,8 +3,6 @@ using System.Diagnostics.CodeAnalysis; using Android.Util; using Android.Widget; -using Jakar.SettingsView.Droid.BaseCell; -using Jakar.SettingsView.Shared.CellBase; using Jakar.SettingsView.Shared.Config; using Jakar.SettingsView.Shared.Interfaces; using Xamarin.Forms; @@ -13,10 +11,9 @@ using AContext = Android.Content.Context; using AView = Android.Views.View; using BaseCellView = Jakar.SettingsView.Droid.BaseCell.BaseCellView; -using AiEntryCell = Jakar.SettingsView.Shared.Cells.EntryCell; #nullable enable -namespace Jakar.SettingsView.Droid.Controls +namespace Jakar.SettingsView.Droid.Controls.Core { [SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")] [Android.Runtime.Preserve(AllMembers = true)] diff --git a/src/SettingsView.Droid/Controls/DescriptionView.cs b/src/SettingsView.Droid/Controls/Core/DescriptionView.cs similarity index 98% rename from src/SettingsView.Droid/Controls/DescriptionView.cs rename to src/SettingsView.Droid/Controls/Core/DescriptionView.cs index c100c68..830abda 100644 --- a/src/SettingsView.Droid/Controls/DescriptionView.cs +++ b/src/SettingsView.Droid/Controls/Core/DescriptionView.cs @@ -11,7 +11,7 @@ using TextAlignment = Xamarin.Forms.TextAlignment; #nullable enable -namespace Jakar.SettingsView.Droid.Controls +namespace Jakar.SettingsView.Droid.Controls.Core { [Android.Runtime.Preserve(AllMembers = true)] public class DescriptionView : BaseTextView diff --git a/src/SettingsView.Droid/Controls/HintView.cs b/src/SettingsView.Droid/Controls/Core/HintView.cs similarity index 98% rename from src/SettingsView.Droid/Controls/HintView.cs rename to src/SettingsView.Droid/Controls/Core/HintView.cs index e9d2a51..27346fd 100644 --- a/src/SettingsView.Droid/Controls/HintView.cs +++ b/src/SettingsView.Droid/Controls/Core/HintView.cs @@ -11,7 +11,7 @@ using TextAlignment = Xamarin.Forms.TextAlignment; #nullable enable -namespace Jakar.SettingsView.Droid.Controls +namespace Jakar.SettingsView.Droid.Controls.Core { public class HintView : BaseTextView { diff --git a/src/SettingsView.Droid/Controls/TitleView.cs b/src/SettingsView.Droid/Controls/Core/TitleView.cs similarity index 98% rename from src/SettingsView.Droid/Controls/TitleView.cs rename to src/SettingsView.Droid/Controls/Core/TitleView.cs index 86d416b..897c1ff 100644 --- a/src/SettingsView.Droid/Controls/TitleView.cs +++ b/src/SettingsView.Droid/Controls/Core/TitleView.cs @@ -9,7 +9,7 @@ using BaseCellView = Jakar.SettingsView.Droid.BaseCell.BaseCellView; #nullable enable -namespace Jakar.SettingsView.Droid.Controls +namespace Jakar.SettingsView.Droid.Controls.Core { [Android.Runtime.Preserve(AllMembers = true)] public class TitleView : BaseTextView diff --git a/src/SettingsView.Droid/Controls/ValueView.cs b/src/SettingsView.Droid/Controls/Core/ValueView.cs similarity index 97% rename from src/SettingsView.Droid/Controls/ValueView.cs rename to src/SettingsView.Droid/Controls/Core/ValueView.cs index 5310fa1..8b037c3 100644 --- a/src/SettingsView.Droid/Controls/ValueView.cs +++ b/src/SettingsView.Droid/Controls/Core/ValueView.cs @@ -1,6 +1,5 @@ using System; using System.ComponentModel; -using System.Runtime.CompilerServices; using Android.Content; using Android.Util; using Android.Views; @@ -12,7 +11,7 @@ using TextAlignment = Xamarin.Forms.TextAlignment; #nullable enable -namespace Jakar.SettingsView.Droid.Controls +namespace Jakar.SettingsView.Droid.Controls.Core { [Android.Runtime.Preserve(AllMembers = true)] public class ValueView : BaseTextView diff --git a/src/SettingsView.Droid/HeaderFooterContainer.cs b/src/SettingsView.Droid/Controls/HeaderFooterContainer.cs similarity index 88% rename from src/SettingsView.Droid/HeaderFooterContainer.cs rename to src/SettingsView.Droid/Controls/HeaderFooterContainer.cs index 2bbfdf1..124ce18 100644 --- a/src/SettingsView.Droid/HeaderFooterContainer.cs +++ b/src/SettingsView.Droid/Controls/HeaderFooterContainer.cs @@ -8,13 +8,14 @@ using Android.Widget; using Jakar.SettingsView.Shared.Config; using Jakar.SettingsView.Shared.Interfaces; +using Jakar.SettingsView.Shared.Misc; using Jakar.SettingsView.Shared.sv; using Xamarin.Forms; using Xamarin.Forms.Internals; using Xamarin.Forms.Platform.Android; #nullable enable -namespace Jakar.SettingsView.Droid +namespace Jakar.SettingsView.Droid.Controls { [Android.Runtime.Preserve(AllMembers = true)] public class HeaderFooterContainer : FrameLayout, INativeElementView @@ -27,7 +28,7 @@ public class HeaderFooterContainer : FrameLayout, INativeElementView protected IVisualElementRenderer? _Renderer { get; set; } - private ISectionFooterHeader? _content; + protected ISectionFooterHeader? _content; protected ISectionFooterHeader? _Content { @@ -64,22 +65,21 @@ protected ISectionFooterHeader? _Content { _content = value; _content.DisableLayout = true; - foreach ( var element in _content.Descendants() ) + foreach ( var element in _content.View.Descendants() ) { if ( element is VisualElement v ) v.DisableLayout = true; } renderer.SetElement(_content.View); - Platform.SetRenderer(_content.View, _Renderer); _content.DisableLayout = false; - foreach ( var element in _content.Descendants() ) + foreach ( var element in _content.View.Descendants() ) { if ( element is VisualElement v ) v.DisableLayout = false; } - var viewAsLayout = _Content as Layout; + var viewAsLayout = _content.View as Layout; viewAsLayout?.ForceLayout(); Update(); @@ -143,7 +143,6 @@ protected override void OnLayout( bool changed, _Renderer.UpdateLayout(); } - protected override void OnMeasure( int widthMeasureSpec, int heightMeasureSpec ) { int width = MeasureSpec.GetSize(widthMeasureSpec); @@ -174,16 +173,16 @@ protected override void OnMeasure( int widthMeasureSpec, int heightMeasureSpec ) public virtual void CellPropertyChanged( object sender, PropertyChangedEventArgs e ) { - if ( e.PropertyName == Cell.IsEnabledProperty.PropertyName ) { UpdateIsEnabled(); } - else if ( e.PropertyName == Section.TitleProperty.PropertyName ) { UpdateTitle(); } - else if ( e.PropertyName == Section.TextColorProperty.PropertyName ) { UpdateTextColor(); } - else if ( e.PropertyName == VisualElement.IsEnabledProperty.PropertyName ) { UpdateIsEnabled(); } - else if ( e.PropertyName == HeaderView.IsCollapsedProperty.PropertyName ) { ShowHideSection(); } - else if ( e.PropertyName == HeaderView.IsCollapsibleProperty.PropertyName ) { UpdateIsCollapsible(); } + if ( e.IsEqual(Cell.IsEnabledProperty) ) { UpdateIsEnabled(); } + else if ( e.IsEqual(Section.TitleProperty) ) { UpdateTitle(); } + else if ( e.IsEqual(Section.TextColorProperty) ) { UpdateTextColor(); } + else if ( e.IsEqual(VisualElement.IsEnabledProperty) ) { UpdateIsEnabled(); } + else if ( e.IsEqual(HeaderView.IsCollapsedProperty) ) { ShowHideSection(); } + else if ( e.IsEqual(HeaderView.IsCollapsibleProperty) ) { UpdateIsCollapsible(); } } - private void UpdateIsCollapsible() { Clickable = _Header?.IsCollapsible ?? false; } - private void ShowHideSection() { _Content?.Section?.ShowHideSection(); } - private void UpdateTitle() + protected void UpdateIsCollapsible() { Clickable = _Header?.IsCollapsible ?? false; } + protected void ShowHideSection() { _Content?.Section?.ShowHideSection(); } + protected void UpdateTitle() { if ( _Content is null ) throw new NullReferenceException(nameof(_Content)); if ( _Content.Section is null ) throw new NullReferenceException(nameof(_Content.Section)); @@ -192,7 +191,7 @@ private void UpdateTitle() if ( _Content is ISectionFooter footer ) { footer.SetText(_Content.Section.FooterText); } } - private void UpdateTextColor() + protected void UpdateTextColor() { if ( _Content is null ) throw new NullReferenceException(nameof(_Content)); if ( _Content.Section is null ) throw new NullReferenceException(nameof(_Content.Section)); diff --git a/src/SettingsView.Droid/Jakar.SettingsView.Droid.csproj b/src/SettingsView.Droid/Jakar.SettingsView.Droid.csproj index 59f31db..dae92a1 100644 --- a/src/SettingsView.Droid/Jakar.SettingsView.Droid.csproj +++ b/src/SettingsView.Droid/Jakar.SettingsView.Droid.csproj @@ -53,13 +53,13 @@ - - - + + + - - + + @@ -95,7 +95,7 @@ - + @@ -186,5 +186,6 @@ + \ No newline at end of file diff --git a/src/SettingsView.Droid/SettingsViewRecyclerAdapter.cs b/src/SettingsView.Droid/SettingsViewRecyclerAdapter.cs index 886c517..b89baa4 100644 --- a/src/SettingsView.Droid/SettingsViewRecyclerAdapter.cs +++ b/src/SettingsView.Droid/SettingsViewRecyclerAdapter.cs @@ -5,6 +5,7 @@ using Android.Views; using Android.Widget; using AndroidX.RecyclerView.Widget; +using Jakar.SettingsView.Droid.Controls; using Jakar.SettingsView.Droid.Extensions; using Jakar.SettingsView.Shared; using Jakar.SettingsView.Shared.Config; diff --git a/src/SettingsView.Droid/ViewHolders.cs b/src/SettingsView.Droid/ViewHolders.cs index 6691a06..abc3c37 100644 --- a/src/SettingsView.Droid/ViewHolders.cs +++ b/src/SettingsView.Droid/ViewHolders.cs @@ -1,6 +1,7 @@ using System; using Android.Widget; using AndroidX.RecyclerView.Widget; +using Jakar.SettingsView.Droid.Controls; using Xamarin.Forms; using AView = Android.Views.View; diff --git a/src/SettingsView.iOS/BaseCell/BaseAiDescriptionCell.cs b/src/SettingsView.iOS/BaseCell/BaseAiDescriptionCell.cs index c106d24..eceae62 100644 --- a/src/SettingsView.iOS/BaseCell/BaseAiDescriptionCell.cs +++ b/src/SettingsView.iOS/BaseCell/BaseAiDescriptionCell.cs @@ -1,6 +1,7 @@ using System; using System.ComponentModel; using Jakar.SettingsView.iOS.Controls; +using Jakar.SettingsView.iOS.Controls.Core; using Jakar.SettingsView.Shared.Config; using UIKit; using Xamarin.Forms; diff --git a/src/SettingsView.iOS/BaseCell/BaseAiTitledCell.cs b/src/SettingsView.iOS/BaseCell/BaseAiTitledCell.cs index 1b990c4..4f504eb 100644 --- a/src/SettingsView.iOS/BaseCell/BaseAiTitledCell.cs +++ b/src/SettingsView.iOS/BaseCell/BaseAiTitledCell.cs @@ -1,6 +1,7 @@ using System; using System.ComponentModel; using Jakar.SettingsView.iOS.Controls; +using Jakar.SettingsView.iOS.Controls.Core; using UIKit; using Xamarin.Forms; diff --git a/src/SettingsView.iOS/BaseCell/BaseAiValueCell.cs b/src/SettingsView.iOS/BaseCell/BaseAiValueCell.cs index 474f57c..46bb095 100644 --- a/src/SettingsView.iOS/BaseCell/BaseAiValueCell.cs +++ b/src/SettingsView.iOS/BaseCell/BaseAiValueCell.cs @@ -1,6 +1,7 @@ using System; using System.ComponentModel; using Jakar.SettingsView.iOS.Controls; +using Jakar.SettingsView.iOS.Controls.Core; using Xamarin.Forms; #nullable enable diff --git a/src/SettingsView.iOS/BaseCell/BaseCellView.cs b/src/SettingsView.iOS/BaseCell/BaseCellView.cs index 83828ab..b6f043f 100644 --- a/src/SettingsView.iOS/BaseCell/BaseCellView.cs +++ b/src/SettingsView.iOS/BaseCell/BaseCellView.cs @@ -14,7 +14,7 @@ #nullable enable namespace Jakar.SettingsView.iOS.BaseCell { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public abstract class BaseCellView : CellTableViewCell { // internal NSLayoutConstraint LeftMarginConstraint { get; private set; } diff --git a/src/SettingsView.iOS/BaseCell/BasePickerCell.cs b/src/SettingsView.iOS/BaseCell/BasePickerCell.cs index 2db0370..e90233a 100644 --- a/src/SettingsView.iOS/BaseCell/BasePickerCell.cs +++ b/src/SettingsView.iOS/BaseCell/BasePickerCell.cs @@ -2,13 +2,13 @@ using System.Diagnostics.CodeAnalysis; using Foundation; -using Jakar.SettingsView.iOS.OLD_Cells; +using Jakar.SettingsView.iOS.Controls; using UIKit; using Xamarin.Forms; namespace Jakar.SettingsView.iOS.BaseCell { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public abstract class BasePickerCell : BaseAiValueCell { protected NoCaretField _DummyField { get; set; } diff --git a/src/SettingsView.iOS/BaseCell/BaseValueCell.cs b/src/SettingsView.iOS/BaseCell/BaseValueCell.cs index 9539bef..a973b0a 100644 --- a/src/SettingsView.iOS/BaseCell/BaseValueCell.cs +++ b/src/SettingsView.iOS/BaseCell/BaseValueCell.cs @@ -1,5 +1,6 @@ using System; using Jakar.SettingsView.iOS.Controls; +using Jakar.SettingsView.iOS.Controls.Core; using Jakar.SettingsView.Shared.Config; using Jakar.SettingsView.Shared.Misc; using UIKit; diff --git a/src/SettingsView.iOS/BaseCell/CellBaseRenderer.cs b/src/SettingsView.iOS/BaseCell/CellBaseRenderer.cs index 6656a38..b7cc7b8 100644 --- a/src/SettingsView.iOS/BaseCell/CellBaseRenderer.cs +++ b/src/SettingsView.iOS/BaseCell/CellBaseRenderer.cs @@ -1,7 +1,6 @@ using System; using System.Linq.Expressions; using System.Reflection; -using Jakar.SettingsView.iOS.OLD_Cells; using Jakar.SettingsView.Shared.CellBase; using Jakar.SettingsView.Shared.sv; using UIKit; @@ -10,17 +9,10 @@ namespace Jakar.SettingsView.iOS.BaseCell { - /// - /// Cell base renderer. - /// [Foundation.Preserve(AllMembers = true)] public class CellBaseRenderer : CellRenderer where TnativeCell : BaseCellView { - /// - /// Refer to - /// http://qiita.com/Temarin/items/d6f00428743b0971ec95 /// http://neue.cc/2014/09/16_478.html - /// internal static class InstanceCreator { public static Func Create { get; } = CreateInstance(); @@ -39,14 +31,7 @@ private static Func CreateInstance() return Expression.Lambda>(Expression.New(constructor, arg1), arg1).Compile(); } } - - /// - /// Gets the cell. - /// - /// The cell. - /// Item. - /// Reusable cell. - /// Tv. + public override UITableViewCell GetCell( Cell item, UITableViewCell reusableCell, UITableView tv ) { var nativeCell = reusableCell as TnativeCell; @@ -80,7 +65,6 @@ protected void SetUpPropertyChanged( BaseCellView nativeCell ) formsCell.Section = section; formsCell.Section.PropertyChanged += nativeCell.SectionPropertyChanged; } - protected void ClearPropertyChanged( BaseCellView nativeCell ) { if ( nativeCell.Cell is not CellBase formsCell ) @@ -94,40 +78,42 @@ protected void ClearPropertyChanged( BaseCellView nativeCell ) if ( formsCell.Section != null ) { formsCell.Section.PropertyChanged -= nativeCell.SectionPropertyChanged; } } - protected void SetUpPropertyChanged( CellBaseView nativeCell ) - { - var formsCell = nativeCell.Cell as CellBase; - var parentElement = formsCell.Parent as Shared.sv.SettingsView; - - formsCell.PropertyChanged += nativeCell.CellPropertyChanged; - - if ( parentElement != null ) - { - parentElement.PropertyChanged += nativeCell.ParentPropertyChanged; - Section section = parentElement.Model.GetSection(SettingsModel.GetPath(formsCell).Item1); - if ( section != null ) - { - formsCell.Section = section; - formsCell.Section.PropertyChanged += nativeCell.SectionPropertyChanged; - } - } - } - - private void ClearPropertyChanged( CellBaseView nativeCell ) - { - var formsCell = nativeCell.Cell as CellBase; - - if ( formsCell is null ) - return; // for HotReload - var parentElement = formsCell.Parent as Shared.sv.SettingsView; - formsCell.PropertyChanged -= nativeCell.CellPropertyChanged; - if ( parentElement != null ) - { - parentElement.PropertyChanged -= nativeCell.ParentPropertyChanged; - if ( formsCell.Section != null ) { formsCell.Section.PropertyChanged -= nativeCell.SectionPropertyChanged; } - } - } + // protected void SetUpPropertyChanged( CellBaseView nativeCell ) + // { + // var formsCell = nativeCell.Cell as CellBase; + // var parentElement = formsCell.Parent as Shared.sv.SettingsView; + // + // formsCell.PropertyChanged += nativeCell.CellPropertyChanged; + // + // if ( parentElement != null ) + // { + // parentElement.PropertyChanged += nativeCell.ParentPropertyChanged; + // Section section = parentElement.Model.GetSection(SettingsModel.GetPath(formsCell).Item1); + // if ( section != null ) + // { + // formsCell.Section = section; + // formsCell.Section.PropertyChanged += nativeCell.SectionPropertyChanged; + // } + // } + // } + // + // private void ClearPropertyChanged( CellBaseView nativeCell ) + // { + // var formsCell = nativeCell.Cell as CellBase; + // + // if ( formsCell is null ) + // return; // for HotReload + // + // var parentElement = formsCell.Parent as Shared.sv.SettingsView; + // + // formsCell.PropertyChanged -= nativeCell.CellPropertyChanged; + // if ( parentElement != null ) + // { + // parentElement.PropertyChanged -= nativeCell.ParentPropertyChanged; + // if ( formsCell.Section != null ) { formsCell.Section.PropertyChanged -= nativeCell.SectionPropertyChanged; } + // } + // } } } \ No newline at end of file diff --git a/src/SettingsView.iOS/Cells/AccessoryCells/CheckboxCellRenderer.cs b/src/SettingsView.iOS/Cells/AccessoryCells/CheckboxCellRenderer.cs index bcf14a8..900abf6 100644 --- a/src/SettingsView.iOS/Cells/AccessoryCells/CheckboxCellRenderer.cs +++ b/src/SettingsView.iOS/Cells/AccessoryCells/CheckboxCellRenderer.cs @@ -15,10 +15,10 @@ #nullable enable namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class CheckboxCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class CheckboxCellView : BaseAiAccessoryCell { protected CheckboxCell _AccessoryCell => Cell as CheckboxCell ?? throw new NullReferenceException(nameof(_AccessoryCell)); diff --git a/src/SettingsView.iOS/Cells/AccessoryCells/SwitchCellRenderer.cs b/src/SettingsView.iOS/Cells/AccessoryCells/SwitchCellRenderer.cs index 78cc1f4..e34a601 100644 --- a/src/SettingsView.iOS/Cells/AccessoryCells/SwitchCellRenderer.cs +++ b/src/SettingsView.iOS/Cells/AccessoryCells/SwitchCellRenderer.cs @@ -16,10 +16,10 @@ #nullable enable namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class SwitchCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class SwitchCellView : BaseAiAccessoryCell { protected SwitchCell _AccessoryCell => Cell as SwitchCell ?? throw new NullReferenceException(nameof(_AccessoryCell)); diff --git a/src/SettingsView.iOS/Cells/CommandCells/ButtonCellRenderer.cs b/src/SettingsView.iOS/Cells/CommandCells/ButtonCellRenderer.cs index d469058..ac9a932 100644 --- a/src/SettingsView.iOS/Cells/CommandCells/ButtonCellRenderer.cs +++ b/src/SettingsView.iOS/Cells/CommandCells/ButtonCellRenderer.cs @@ -3,8 +3,8 @@ using System.Windows.Input; using Foundation; using Jakar.SettingsView.iOS.BaseCell; +using Jakar.SettingsView.iOS.Cells; using Jakar.SettingsView.iOS.Extensions; -using Jakar.SettingsView.iOS.OLD_Cells; using Jakar.SettingsView.Shared.CellBase; using Jakar.SettingsView.Shared.Cells; using Jakar.SettingsView.Shared.Config; @@ -17,9 +17,9 @@ namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] internal class ButtonCellRenderer : CellBaseRenderer { } + [Preserve(AllMembers = true)] internal class ButtonCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class ButtonCellView : BaseCellView // IBorderVisualElementRenderer { protected internal UIColor? DefaultTextColor { get; } diff --git a/src/SettingsView.iOS/Cells/CommandCells/CommandCellRenderer.cs b/src/SettingsView.iOS/Cells/CommandCells/CommandCellRenderer.cs index 64d7fe8..411495b 100644 --- a/src/SettingsView.iOS/Cells/CommandCells/CommandCellRenderer.cs +++ b/src/SettingsView.iOS/Cells/CommandCells/CommandCellRenderer.cs @@ -3,7 +3,7 @@ using System.Windows.Input; using Foundation; using Jakar.SettingsView.iOS.BaseCell; -using Jakar.SettingsView.iOS.OLD_Cells; +using Jakar.SettingsView.iOS.Cells; using Jakar.SettingsView.Shared.Cells; using UIKit; using Xamarin.Forms; @@ -13,11 +13,11 @@ #nullable enable namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class CommandCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class CommandCellView : BaseAiDescriptionCell { protected ICommand? _Command { get; set; } diff --git a/src/SettingsView.iOS/Cells/EntryCellRenderer.cs b/src/SettingsView.iOS/Cells/EntryCellRenderer.cs index 118fd61..d5bea45 100644 --- a/src/SettingsView.iOS/Cells/EntryCellRenderer.cs +++ b/src/SettingsView.iOS/Cells/EntryCellRenderer.cs @@ -16,10 +16,10 @@ #nullable enable namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class EntryCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class EntryCellView : BaseValueCell, IEntryCellRenderer { protected bool _HasFocus { get; set; } diff --git a/src/SettingsView.iOS/Cells/Pickers/DatePickerCellRenderer.cs b/src/SettingsView.iOS/Cells/Pickers/DatePickerCellRenderer.cs index 9aac477..ba4623e 100644 --- a/src/SettingsView.iOS/Cells/Pickers/DatePickerCellRenderer.cs +++ b/src/SettingsView.iOS/Cells/Pickers/DatePickerCellRenderer.cs @@ -4,7 +4,6 @@ using Foundation; using Jakar.SettingsView.iOS.BaseCell; using Jakar.SettingsView.iOS.Cells; -using Jakar.SettingsView.iOS.OLD_Cells; using Jakar.SettingsView.Shared.Cells; using Jakar.SettingsView.Shared.Misc; using UIKit; @@ -16,10 +15,10 @@ #nullable enable namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class DatePickerCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class DatePickerCellView : BasePickerCell { protected DatePickerCell _DatePickerCell => Cell as DatePickerCell ?? throw new NullReferenceException(nameof(_DatePickerCell)); diff --git a/src/SettingsView.iOS/Cells/Pickers/NumberPickerCell.cs b/src/SettingsView.iOS/Cells/Pickers/NumberPickerCell.cs index 094eeb5..c585902 100644 --- a/src/SettingsView.iOS/Cells/Pickers/NumberPickerCell.cs +++ b/src/SettingsView.iOS/Cells/Pickers/NumberPickerCell.cs @@ -6,7 +6,6 @@ using Jakar.SettingsView.iOS.BaseCell; using Jakar.SettingsView.iOS.Cells; using Jakar.SettingsView.iOS.Cells.Sources; -using Jakar.SettingsView.iOS.OLD_Cells; using Jakar.SettingsView.Shared.Cells; using Jakar.SettingsView.Shared.Config; using Jakar.SettingsView.Shared.Misc; @@ -19,11 +18,11 @@ #nullable enable namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class NumberPickerCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class NumberPickerCellView : BasePickerCell { protected NumberPickerCell _NumberPickerCell => Cell as NumberPickerCell ?? throw new NullReferenceException(nameof(_NumberPickerCell)); diff --git a/src/SettingsView.iOS/Cells/Pickers/PickerCellRenderer.cs b/src/SettingsView.iOS/Cells/Pickers/PickerCellRenderer.cs index f2d1554..f7a389c 100644 --- a/src/SettingsView.iOS/Cells/Pickers/PickerCellRenderer.cs +++ b/src/SettingsView.iOS/Cells/Pickers/PickerCellRenderer.cs @@ -19,10 +19,10 @@ #nullable enable namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] public class PickerCellRenderer : CellBaseRenderer { } + [Preserve(AllMembers = true)] public class PickerCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class PickerCellView : BasePickerCell { protected PickerCell _PickerCell => Cell as PickerCell ?? throw new NullReferenceException(nameof(_PickerCell)); diff --git a/src/SettingsView.iOS/Cells/Pickers/TimePickerCellRenderer.cs b/src/SettingsView.iOS/Cells/Pickers/TimePickerCellRenderer.cs index 9c5f326..e2fef0b 100644 --- a/src/SettingsView.iOS/Cells/Pickers/TimePickerCellRenderer.cs +++ b/src/SettingsView.iOS/Cells/Pickers/TimePickerCellRenderer.cs @@ -17,10 +17,10 @@ #nullable enable namespace Jakar.SettingsView.iOS.Cells { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class TimePickerCellRenderer : CellBaseRenderer { } - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class TimePickerCellView : BasePickerCell { protected TimePickerCell _TimePickerCell => Cell as TimePickerCell ?? throw new NullReferenceException(nameof(_TimePickerCell)); diff --git a/src/SettingsView.iOS/Controls/AiEditText.cs b/src/SettingsView.iOS/Controls/AiEditText.cs index 70de7eb..fa0d433 100644 --- a/src/SettingsView.iOS/Controls/AiEditText.cs +++ b/src/SettingsView.iOS/Controls/AiEditText.cs @@ -17,7 +17,7 @@ #nullable enable namespace Jakar.SettingsView.iOS.Controls { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class AiEditText : UITextField, IUpdateEntryCell { protected bool _HasFocus { get; set; } diff --git a/src/SettingsView.iOS/Controls/BaseTextView.cs b/src/SettingsView.iOS/Controls/Core/BaseTextView.cs similarity index 96% rename from src/SettingsView.iOS/Controls/BaseTextView.cs rename to src/SettingsView.iOS/Controls/Core/BaseTextView.cs index 04366dd..c6939de 100644 --- a/src/SettingsView.iOS/Controls/BaseTextView.cs +++ b/src/SettingsView.iOS/Controls/Core/BaseTextView.cs @@ -6,10 +6,9 @@ using UIKit; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; -using BaseCellView = Jakar.SettingsView.iOS.BaseCell.BaseCellView; #nullable enable -namespace Jakar.SettingsView.iOS.Controls +namespace Jakar.SettingsView.iOS.Controls.Core { [SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")] [Foundation.Preserve(AllMembers = true)] diff --git a/src/SettingsView.iOS/Controls/DescriptionView.cs b/src/SettingsView.iOS/Controls/Core/DescriptionView.cs similarity index 96% rename from src/SettingsView.iOS/Controls/DescriptionView.cs rename to src/SettingsView.iOS/Controls/Core/DescriptionView.cs index 2de6446..364439d 100644 --- a/src/SettingsView.iOS/Controls/DescriptionView.cs +++ b/src/SettingsView.iOS/Controls/Core/DescriptionView.cs @@ -5,11 +5,10 @@ using Jakar.SettingsView.Shared.CellBase; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; -using BaseCellView = Jakar.SettingsView.iOS.BaseCell.BaseCellView; using TextAlignment = Xamarin.Forms.TextAlignment; #nullable enable -namespace Jakar.SettingsView.iOS.Controls +namespace Jakar.SettingsView.iOS.Controls.Core { [Foundation.Preserve(AllMembers = true)] public class DescriptionView : BaseTextView diff --git a/src/SettingsView.iOS/Controls/HintView.cs b/src/SettingsView.iOS/Controls/Core/HintView.cs similarity index 96% rename from src/SettingsView.iOS/Controls/HintView.cs rename to src/SettingsView.iOS/Controls/Core/HintView.cs index 5b479d5..8adb7cb 100644 --- a/src/SettingsView.iOS/Controls/HintView.cs +++ b/src/SettingsView.iOS/Controls/Core/HintView.cs @@ -6,11 +6,10 @@ using UIKit; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; -using BaseCellView = Jakar.SettingsView.iOS.BaseCell.BaseCellView; using TextAlignment = Xamarin.Forms.TextAlignment; #nullable enable -namespace Jakar.SettingsView.iOS.Controls +namespace Jakar.SettingsView.iOS.Controls.Core { [Foundation.Preserve(AllMembers = true)] public class HintView : BaseTextView> where TCell : UIView diff --git a/src/SettingsView.iOS/Controls/TitleView.cs b/src/SettingsView.iOS/Controls/Core/TitleView.cs similarity index 95% rename from src/SettingsView.iOS/Controls/TitleView.cs rename to src/SettingsView.iOS/Controls/Core/TitleView.cs index a5bffff..e46c134 100644 --- a/src/SettingsView.iOS/Controls/TitleView.cs +++ b/src/SettingsView.iOS/Controls/Core/TitleView.cs @@ -1,15 +1,13 @@ using System; using System.ComponentModel; -using System.Runtime.Remoting.Contexts; using Jakar.SettingsView.iOS.BaseCell; using Jakar.SettingsView.iOS.Extensions; using Jakar.SettingsView.Shared.CellBase; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; -using BaseCellView = Jakar.SettingsView.iOS.BaseCell.BaseCellView; #nullable enable -namespace Jakar.SettingsView.iOS.Controls +namespace Jakar.SettingsView.iOS.Controls.Core { [Foundation.Preserve(AllMembers = true)] public class TitleView : BaseTextView diff --git a/src/SettingsView.iOS/Controls/ValueView.cs b/src/SettingsView.iOS/Controls/Core/ValueView.cs similarity index 96% rename from src/SettingsView.iOS/Controls/ValueView.cs rename to src/SettingsView.iOS/Controls/Core/ValueView.cs index b88559b..17b8706 100644 --- a/src/SettingsView.iOS/Controls/ValueView.cs +++ b/src/SettingsView.iOS/Controls/Core/ValueView.cs @@ -5,11 +5,10 @@ using Jakar.SettingsView.Shared.CellBase; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; -using BaseCellView = Jakar.SettingsView.iOS.BaseCell.BaseCellView; using TextAlignment = Xamarin.Forms.TextAlignment; #nullable enable -namespace Jakar.SettingsView.iOS.Controls +namespace Jakar.SettingsView.iOS.Controls.Core { [Foundation.Preserve(AllMembers = true)] public class ValueView : BaseTextView diff --git a/src/SettingsView.iOS/OLD_Cells/NoCaretField.cs b/src/SettingsView.iOS/Controls/NoCaretField.cs similarity index 88% rename from src/SettingsView.iOS/OLD_Cells/NoCaretField.cs rename to src/SettingsView.iOS/Controls/NoCaretField.cs index 5162b54..0a46e6d 100644 --- a/src/SettingsView.iOS/OLD_Cells/NoCaretField.cs +++ b/src/SettingsView.iOS/Controls/NoCaretField.cs @@ -1,7 +1,7 @@ using CoreGraphics; using UIKit; -namespace Jakar.SettingsView.iOS.OLD_Cells +namespace Jakar.SettingsView.iOS.Controls { [Foundation.Preserve(AllMembers = true)] public class NoCaretField : UITextField diff --git a/src/SettingsView.iOS/CustomHeaderFooterView.cs b/src/SettingsView.iOS/CustomHeaderFooterView.cs index ce74b65..905c756 100644 --- a/src/SettingsView.iOS/CustomHeaderFooterView.cs +++ b/src/SettingsView.iOS/CustomHeaderFooterView.cs @@ -1,10 +1,16 @@ using System; using System.ComponentModel; using System.Reflection; +using Jakar.SettingsView.iOS.Extensions; +using Jakar.SettingsView.Shared.Config; +using Jakar.SettingsView.Shared.Interfaces; +using Jakar.SettingsView.Shared.Misc; +using Jakar.SettingsView.Shared.sv; using UIKit; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; +#nullable enable namespace Jakar.SettingsView.iOS { public class CustomHeaderView : CustomHeaderFooterView @@ -19,118 +25,160 @@ public CustomFooterView( IntPtr handle ) : base(handle) { } public class CustomHeaderFooterView : UITableViewHeaderFooterView { - private WeakReference _rendererRef; - private bool _disposed; - private NSLayoutConstraint _heightConstraint; - private View _formsCell; + private ISectionFooterHeader? _content; + protected WeakReference? _RendererRef { get; set; } + protected bool _Disposed { get; set; } + protected UITableView? _TableView { get; set; } + protected NSLayoutConstraint? _HeightConstraint { get; set; } - public CustomHeaderFooterView( IntPtr handle ) : base(handle) { } - - protected override void Dispose( bool disposing ) + protected ISectionFooterHeader? _Content { - if ( _disposed ) { return; } - - if ( disposing ) + get => _content; + set { - if ( _formsCell != null ) { _formsCell.PropertyChanged -= CellPropertyChanged; } + if ( _content == value ) { return; } - _heightConstraint?.Dispose(); - _heightConstraint = null; + if ( _content != null ) { _content.PropertyChanged -= CellPropertyChanged; } - IVisualElementRenderer renderer = null; - if ( _rendererRef != null && - _rendererRef.TryGetTarget(out renderer) && - renderer.Element != null ) + _content = value; + if ( _content is null ) return; + if ( _TableView is null ) throw new NullReferenceException(nameof(_TableView)); + + _content.PropertyChanged += CellPropertyChanged; + + if ( _RendererRef == null || + !_RendererRef.TryGetTarget(out IVisualElementRenderer renderer) ) { - FormsInternals.DisposeModelAndChildrenRenderers(renderer.Element); - _rendererRef = null; + renderer = GetNewRenderer(_content, ContentView); + _RendererRef = new WeakReference(renderer); + } + else + { + if ( renderer.Element != null && + renderer == Platform.GetRenderer(renderer.Element) ) + renderer.Element.ClearValue(FormsInternals.RendererProperty); + + Type type = Xamarin.Forms.Internals.Registrar.Registered.GetHandlerTypeForObject(_content.View); + // ReSharper disable once SuspiciousTypeConversion.Global + Type rendererType = renderer is IReflectableType reflectableType + ? reflectableType.GetTypeInfo().AsType() + : renderer.GetType(); + if ( rendererType == type || + ( renderer.GetType() == FormsInternals.DefaultRenderer ) && type == null ) + renderer.SetElement(_content.View); + 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 + FormsInternals.DisposeRendererAndChildren(renderer); + renderer = GetNewRenderer(_content, ContentView); + _RendererRef = new WeakReference(renderer); + } } - renderer?.Dispose(); + Platform.SetRenderer(_content.View, renderer); - _formsCell = null; - } + if ( renderer.Element != null ) + { + SizeRequest result = renderer.Element.Measure(_TableView.Frame.Width, double.PositiveInfinity, MeasureFlags.IncludeMargins); + double finalW = result.Request.Width; + if ( _content.View.HorizontalOptions.Alignment == LayoutAlignment.Fill ) { finalW = _TableView.Frame.Width; } - _disposed = true; + var finalH = (float) result.Request.Height; - base.Dispose(disposing); - } + UpdateNativeCell(); - public virtual void UpdateNativeCell() { UpdateIsEnabled(); } + if ( _HeightConstraint != null ) + { + _HeightConstraint.Active = false; + _HeightConstraint?.Dispose(); + } - public virtual void CellPropertyChanged( object sender, PropertyChangedEventArgs e ) - { - if ( e.PropertyName == Cell.IsEnabledProperty.PropertyName ) { UpdateIsEnabled(); } + _HeightConstraint = renderer.NativeView.HeightAnchor.ConstraintEqualTo(finalH); + _HeightConstraint.Priority = SVConstants.Layout.Priority.HIGH; + _HeightConstraint.Active = true; + renderer.NativeView.AddConstraint(_HeightConstraint); + + Layout.LayoutChildIntoBoundingRegion(_content.View, new Rectangle(0, 0, finalW, finalH)); + } + + foreach ( var element in _content.View.Descendants() ) + { + if ( element is VisualElement v ) + v.DisableLayout = false; + } + + renderer.NativeView.UpdateConstraintsIfNeeded(); + renderer.NativeView.SetNeedsDisplay(); + } } - protected virtual void UpdateIsEnabled() { UserInteractionEnabled = _formsCell.IsEnabled; } + protected ISectionHeader? _Header => _content as ISectionHeader; - public virtual void UpdateCell( View cell, UITableView tableView ) + public CustomHeaderFooterView( IntPtr handle ) : base(handle) { } + + protected override void Dispose( bool disposing ) { - if ( _formsCell == cell ) { return; } + if ( _Disposed ) { return; } - if ( _formsCell != null ) { _formsCell.PropertyChanged -= CellPropertyChanged; } + if ( disposing ) + { + if ( _Content != null ) { _Content.PropertyChanged -= CellPropertyChanged; } - _formsCell = cell; - _formsCell.PropertyChanged += CellPropertyChanged; + _TableView?.Dispose(); + _TableView = null; - IVisualElementRenderer renderer; - if ( _rendererRef == null || - !_rendererRef.TryGetTarget(out renderer) ) { renderer = GetNewRenderer(); } - else - { - if ( renderer.Element != null && - renderer == Platform.GetRenderer(renderer.Element) ) - renderer.Element.ClearValue(FormsInternals.RendererProperty); - - Type type = Xamarin.Forms.Internals.Registrar.Registered.GetHandlerTypeForObject(_formsCell); - var reflectableType = renderer as IReflectableType; - Type rendererType = reflectableType != null - ? reflectableType.GetTypeInfo().AsType() - : renderer.GetType(); - if ( rendererType == type || - ( renderer.GetType() == FormsInternals.DefaultRenderer ) && type == null ) - renderer.SetElement(_formsCell); - else + _HeightConstraint?.Dispose(); + _HeightConstraint = null; + + if ( _RendererRef != null && + _RendererRef.TryGetTarget(out IVisualElementRenderer renderer) && + renderer.Element != null ) { - //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 - FormsInternals.DisposeRendererAndChildren(renderer); - renderer = GetNewRenderer(); + FormsInternals.DisposeModelAndChildrenRenderers(renderer.Element); + _RendererRef = null; + renderer.Dispose(); } + + _Content = null; } - Platform.SetRenderer(_formsCell, renderer); + _Disposed = true; - double height = double.PositiveInfinity; - SizeRequest result = renderer.Element.Measure(tableView.Frame.Width, height, MeasureFlags.IncludeMargins); - double finalW = result.Request.Width; - if ( _formsCell.HorizontalOptions.Alignment == LayoutAlignment.Fill ) { finalW = tableView.Frame.Width; } + base.Dispose(disposing); + } - var finalH = (float) result.Request.Height; + public virtual void UpdateNativeCell() { UpdateIsEnabled(); } - UpdateNativeCell(); + public virtual void CellPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + if ( e.IsEqual(Cell.IsEnabledProperty) ) { UpdateIsEnabled(); } + else if ( e.IsEqual(Section.TitleProperty) ) { UpdateTitle(); } + else if ( e.IsEqual(Section.TextColorProperty) ) { UpdateTextColor(); } + else if ( e.IsEqual(VisualElement.IsEnabledProperty) ) { UpdateIsEnabled(); } + else if ( e.IsEqual(HeaderView.IsCollapsedProperty) ) { ShowHideSection(); } + else if ( e.IsEqual(HeaderView.IsCollapsibleProperty) ) { UpdateIsCollapsible(); } + } - if ( _heightConstraint != null ) - { - _heightConstraint.Active = false; - _heightConstraint?.Dispose(); - } + protected virtual void UpdateIsEnabled() { UserInteractionEnabled = _Content?.IsEnabled ?? false; } - _heightConstraint = renderer.NativeView.HeightAnchor.ConstraintEqualTo(finalH); - _heightConstraint.Priority = 999f; - _heightConstraint.Active = true; + public void SetContent( ISectionHeader content, Section section, UITableView table ) => SetContent(content, section, table, SVConstants.Section.Header.MinRowHeight); + public void SetContent( ISectionFooter content, Section section, UITableView table ) => SetContent(content, section, table, SVConstants.Section.Footer.MinRowHeight); + protected void SetContent( ISectionFooterHeader content, + Section section, + UITableView table, + double minHeight ) + { + _TableView = table; - Layout.LayoutChildIntoBoundingRegion(_formsCell, new Rectangle(0, 0, finalW, finalH)); + content.Section = section; + content.View.HeightRequest = Math.Max(minHeight, content.View.HeightRequest); - renderer.NativeView.UpdateConstraintsIfNeeded(); + _Content = content; } - - protected virtual IVisualElementRenderer GetNewRenderer() + protected static IVisualElementRenderer GetNewRenderer( ISectionFooterHeader content, UIView ContentView ) { - IVisualElementRenderer newRenderer = Platform.CreateRenderer(_formsCell); - _rendererRef = new WeakReference(newRenderer); + IVisualElementRenderer newRenderer = Platform.CreateRenderer(content.View); ContentView.AddSubview(newRenderer.NativeView); UIView native = newRenderer.NativeView; @@ -140,8 +188,37 @@ protected virtual IVisualElementRenderer GetNewRenderer() native.LeftAnchor.ConstraintEqualTo(ContentView.LeftAnchor).Active = true; native.BottomAnchor.ConstraintEqualTo(ContentView.BottomAnchor).Active = true; native.RightAnchor.ConstraintEqualTo(ContentView.RightAnchor).Active = true; + ContentView.HeightAnchor.ConstraintGreaterThanOrEqualTo(content.View.HeightRequest.ToNFloat()).Active = true; return newRenderer; } + + + public virtual void Update() + { + UpdateIsEnabled(); + UpdateIsCollapsible(); + UpdateTitle(); + UpdateTextColor(); + } + + protected void UpdateIsCollapsible() { UserInteractionEnabled = _Header?.IsCollapsible ?? false; } + protected void ShowHideSection() { _Content?.Section?.ShowHideSection(); } + protected void UpdateTitle() + { + if ( _Content is null ) throw new NullReferenceException(nameof(_Content)); + if ( _Content.Section is null ) throw new NullReferenceException(nameof(_Content.Section)); + + if ( _Content is ISectionHeader header ) { header.SetText(_Content.Section.Title); } + + if ( _Content is ISectionFooter footer ) { footer.SetText(_Content.Section.FooterText); } + } + protected void UpdateTextColor() + { + if ( _Content is null ) throw new NullReferenceException(nameof(_Content)); + if ( _Content.Section is null ) throw new NullReferenceException(nameof(_Content.Section)); + + _Content.SetTextColor(_Content.Section.TextColor); + } } } \ No newline at end of file diff --git a/src/SettingsView.iOS/Extensions/NumberExtensions.cs b/src/SettingsView.iOS/Extensions/NumberExtensions.cs index 8164293..70f4940 100644 --- a/src/SettingsView.iOS/Extensions/NumberExtensions.cs +++ b/src/SettingsView.iOS/Extensions/NumberExtensions.cs @@ -14,5 +14,13 @@ public static class PlatformExtensions public static double ToDouble( this nfloat value ) => value; public static float ToFloat( this nfloat value ) => (float) value; public static int ToInt( this nfloat value ) => (int) value; + + public static nint ToNInt( this double value ) => (nint) value; + public static nint ToNInt( this float value ) => (nint) value; + public static nint ToNInt( this int value ) => value; + + public static double ToDouble( this nint value ) => value; + public static float ToFloat( this nint value ) => value; + public static int ToInt( this nint value ) => (int) value; } } \ No newline at end of file diff --git a/src/SettingsView.iOS/ImageCacheController.cs b/src/SettingsView.iOS/ImageCacheController.cs index f504ce9..4b4634e 100644 --- a/src/SettingsView.iOS/ImageCacheController.cs +++ b/src/SettingsView.iOS/ImageCacheController.cs @@ -3,7 +3,7 @@ namespace Jakar.SettingsView.iOS { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public static class ImageCacheController { public static NSCache Instance diff --git a/src/SettingsView.iOS/Interfaces/IEntryCellRenderer.cs b/src/SettingsView.iOS/Interfaces/IEntryCellRenderer.cs index 45fe7e5..5e54d4c 100644 --- a/src/SettingsView.iOS/Interfaces/IEntryCellRenderer.cs +++ b/src/SettingsView.iOS/Interfaces/IEntryCellRenderer.cs @@ -8,7 +8,7 @@ namespace Jakar.SettingsView.iOS.Interfaces { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public interface IEntryCellRenderer { public void UpdateWithForceLayout( Action updateAction ); diff --git a/src/SettingsView.iOS/Jakar.SettingsView.iOS.csproj b/src/SettingsView.iOS/Jakar.SettingsView.iOS.csproj index 2d10a27..7989bde 100644 --- a/src/SettingsView.iOS/Jakar.SettingsView.iOS.csproj +++ b/src/SettingsView.iOS/Jakar.SettingsView.iOS.csproj @@ -76,14 +76,15 @@ - - - + + + + - - + + @@ -93,33 +94,18 @@ - - - - - - - - - - - - - - - diff --git a/src/SettingsView.iOS/SettingsTableSource.cs b/src/SettingsView.iOS/SettingsTableSource.cs index 8c828f1..4ab918a 100644 --- a/src/SettingsView.iOS/SettingsTableSource.cs +++ b/src/SettingsView.iOS/SettingsTableSource.cs @@ -4,8 +4,8 @@ using Foundation; using Jakar.SettingsView.iOS.BaseCell; using Jakar.SettingsView.iOS.Extensions; -using Jakar.SettingsView.iOS.OLD_Cells; using Jakar.SettingsView.Shared; +using Jakar.SettingsView.Shared.Interfaces; using Jakar.SettingsView.Shared.sv; using ObjCRuntime; using UIKit; @@ -14,7 +14,7 @@ namespace Jakar.SettingsView.iOS { - [Foundation.Preserve(AllMembers = true)] + [Preserve(AllMembers = true)] public class SettingsTableSource : UITableViewSource { protected Shared.sv.SettingsView _SettingsView { get; set; } @@ -101,33 +101,30 @@ public override nfloat GetHeightForHeader( UITableView tableView, nint sectionID // // return (nfloat) _settingsView.HeaderHeight; } - public override UIView GetViewForHeader( UITableView tableView, nint section ) // TODO: fix this + public override UIView GetViewForHeader( UITableView tableView, nint sectionId ) // TODO: fix this { - View formsView = _SettingsView.Model.GetSectionHeaderView((int) section); - if ( formsView != null ) { return GetNativeSectionHeaderFooterView(formsView, tableView, true); } + Section section = _SettingsView.Model.GetSection((int) sectionId); + if ( section is null ) throw new NullReferenceException(nameof(section)); + return GetNativeSectionHeaderFooterView(section.HeaderView, tableView, section); - - if ( tableView.DequeueReusableHeaderFooterView(SettingsViewRenderer.TextHeaderId) is not TextHeaderView headerView ) - { - // for HotReload - return new UIView(); - } - - headerView.Label.Text = _SettingsView.Model.GetSectionTitle((int) section); - headerView.Label.TextColor = _SettingsView.HeaderTextColor == Color.Default - ? UIColor.Gray - : _SettingsView.HeaderTextColor.ToUIColor(); - headerView.Label.Font = FontUtility.CreateNativeFont(_SettingsView.HeaderFontFamily, (float) _SettingsView.HeaderFontSize, _SettingsView.HeaderFontAttributes); - //UIFont.SystemFontOfSize((nfloat)_settingsView.HeaderFontSize); - headerView.BackgroundView.BackgroundColor = _SettingsView.HeaderBackgroundColor.ToUIColor(); - headerView.Label.Padding = _SettingsView.HeaderPadding.ToUIEdgeInsets(); - - Section sec = _SettingsView.Model.GetSection((int) section); - headerView.SetVerticalAlignment(_SettingsView.HeaderTextVerticalAlign); - // if ( sec.HeaderHeight != -1 || - // _settingsView.HeaderHeight != -1 ) { headerView.SetVerticalAlignment(_settingsView.HeaderTextVerticalAlign); } - - return headerView; + // throw new InvalidOperationException(nameof(formsView)); + // if ( tableView.DequeueReusableHeaderFooterView(SettingsViewRenderer.TextHeaderId) is not TextHeaderView headerView ) { return new UIView(); } // for HotReload + // + // headerView.Label.Text = _SettingsView.Model.GetSectionTitle((int) section); + // headerView.Label.TextColor = _SettingsView.HeaderTextColor == Color.Default + // ? UIColor.Gray + // : _SettingsView.HeaderTextColor.ToUIColor(); + // headerView.Label.Font = FontUtility.CreateNativeFont(_SettingsView.HeaderFontFamily, (float) _SettingsView.HeaderFontSize, _SettingsView.HeaderFontAttributes); + // //UIFont.SystemFontOfSize((nfloat)_settingsView.HeaderFontSize); + // headerView.BackgroundView.BackgroundColor = _SettingsView.HeaderBackgroundColor.ToUIColor(); + // headerView.Label.Padding = _SettingsView.HeaderPadding.ToUIEdgeInsets(); + // + // Section sec = _SettingsView.Model.GetSection((int) section); + // headerView.SetVerticalAlignment(_SettingsView.HeaderTextVerticalAlign); + // // if ( sec.HeaderHeight != -1 || + // // _settingsView.HeaderHeight != -1 ) { headerView.SetVerticalAlignment(_settingsView.HeaderTextVerticalAlign); } + // + // return headerView; } public override nfloat GetHeightForFooter( UITableView tableView, nint section ) @@ -153,42 +150,42 @@ public override nfloat GetHeightForFooter( UITableView tableView, nint section ) return UITableView.AutomaticDimension; } - public override UIView GetViewForFooter( UITableView tableView, nint section ) + public override UIView GetViewForFooter( UITableView tableView, nint sectionId ) { - View formsView = _SettingsView.Model.GetSectionFooterView((int) section); - if ( formsView != null ) { return GetNativeSectionHeaderFooterView(formsView, tableView, false); } - - string text = _SettingsView.Model.GetFooterText((int) section); - - if ( string.IsNullOrEmpty(text) ) { return new UIView(CGRect.Empty); } + Section section = _SettingsView.Model.GetSection((int) sectionId); + if ( section is null ) throw new NullReferenceException(nameof(section)); + return GetNativeSectionHeaderFooterView(section.FooterView, tableView, section); - var footerView = tableView.DequeueReusableHeaderFooterView(SettingsViewRenderer.TextFooterId) as TextFooterView; - - if ( footerView is null ) - { - // for HotReload - return new UIView(); - } + // throw new InvalidOperationException(nameof(formsView)); + // string text = _SettingsView.Model.GetFooterText((int) section); + // + // if ( string.IsNullOrEmpty(text) ) { return new UIView(CGRect.Empty); } + // + // if ( tableView.DequeueReusableHeaderFooterView(SettingsViewRenderer.TextFooterId) is not TextFooterView footerView ) { return new UIView(); } // for HotReload + // + // footerView.Label.Text = text; + // footerView.Label.TextColor = _SettingsView.FooterTextColor == Color.Default + // ? UIColor.Gray + // : _SettingsView.FooterTextColor.ToUIColor(); + // footerView.Label.Font = FontUtility.CreateNativeFont(_SettingsView.FooterFontFamily, (float) _SettingsView.FooterFontSize, _SettingsView.FooterFontAttributes); + // //UIFont.SystemFontOfSize((nfloat)_settingsView.FooterFontSize); + // footerView.BackgroundView.BackgroundColor = _SettingsView.FooterBackgroundColor.ToUIColor(); + // footerView.Label.Padding = _SettingsView.FooterPadding.ToUIEdgeInsets(); + // + // return footerView; + } - footerView.Label.Text = text; - footerView.Label.TextColor = _SettingsView.FooterTextColor == Color.Default - ? UIColor.Gray - : _SettingsView.FooterTextColor.ToUIColor(); - footerView.Label.Font = FontUtility.CreateNativeFont(_SettingsView.FooterFontFamily, (float) _SettingsView.FooterFontSize, _SettingsView.FooterFontAttributes); - //UIFont.SystemFontOfSize((nfloat)_settingsView.FooterFontSize); - footerView.BackgroundView.BackgroundColor = _SettingsView.FooterBackgroundColor.ToUIColor(); - footerView.Label.Padding = _SettingsView.FooterPadding.ToUIEdgeInsets(); + protected UIView GetNativeSectionHeaderFooterView( ISectionHeader header, UITableView tableView, Section section ) + { + var nativeView = (CustomHeaderFooterView) tableView.DequeueReusableHeaderFooterView(SettingsViewRenderer.CustomHeaderId); + nativeView.SetContent(header, section, tableView); - return footerView; + return nativeView; } - - private UIView GetNativeSectionHeaderFooterView( View formsView, UITableView tableView, bool isHeader ) + protected UIView GetNativeSectionHeaderFooterView( ISectionFooter footer, UITableView tableView, Section section ) { - string idString = isHeader - ? SettingsViewRenderer.CustomHeaderId - : SettingsViewRenderer.CustomFooterId; - var nativeView = tableView.DequeueReusableHeaderFooterView(idString) as CustomHeaderFooterView; - nativeView?.UpdateCell(formsView, tableView); // TODO: fix this + var nativeView = (CustomHeaderFooterView) tableView.DequeueReusableHeaderFooterView(SettingsViewRenderer.CustomFooterId); + nativeView.SetContent(footer, section, tableView); return nativeView; } diff --git a/src/SettingsView.iOS/SettingsViewRenderer.cs b/src/SettingsView.iOS/SettingsViewRenderer.cs index beb45b2..2d1c9d5 100644 --- a/src/SettingsView.iOS/SettingsViewRenderer.cs +++ b/src/SettingsView.iOS/SettingsViewRenderer.cs @@ -8,6 +8,7 @@ using Jakar.SettingsView.iOS; using Jakar.SettingsView.Shared; using Jakar.SettingsView.Shared.Config; +using Jakar.SettingsView.Shared.Misc; using Jakar.SettingsView.Shared.sv; using MobileCoreServices; using UIKit; @@ -23,10 +24,12 @@ namespace Jakar.SettingsView.iOS [Preserve(AllMembers = true)] public class SettingsViewRenderer : ViewRenderer, IUITableViewDragDelegate, IUITableViewDropDelegate { - internal static readonly string TextHeaderId = "textHeaderView"; - internal static readonly string TextFooterId = "textFooterView"; - internal static readonly string CustomHeaderId = "customHeaderView"; - internal static readonly string CustomFooterId = "customFooterView"; + internal static string TextHeaderId { get; } = "textHeaderView"; + internal static string TextFooterId { get; } = "textFooterView"; + internal static string CustomHeaderId { get; } = "customHeaderView"; + internal static string CustomFooterId { get; } = "customFooterView"; + + protected Page? _ParentPage { get; set; } protected KeyboardInsetTracker? _InsetTracker { get; set; } protected UITableView? _TableView { get; set; } @@ -82,8 +85,9 @@ protected override void OnElementChanged( ElementChangedEventArgs _Root.ElementAt(section).Count; public override int GetSectionCount() => _Root.Count(); - public virtual Section GetSection( int section ) => _Root.ElementAtOrDefault(section); - public virtual Section GetSectionFromCell( Cell cell ) { return _Root.FirstOrDefault(x => x.Contains(cell)); } + public virtual Section? GetSection( int section ) => _Root.ElementAtOrDefault(section); + public virtual Section? GetSectionFromCell( Cell cell ) { return _Root.FirstOrDefault(x => x.Contains(cell)); } public virtual int GetSectionIndex( Section section ) => _Root.IndexOf(section); - public override string GetSectionTitle( int section ) => _Root.ElementAt(section).Title; + public override string? GetSectionTitle( int section ) => _Root.ElementAt(section).Title; - public virtual View GetSectionHeaderView( int section ) => _Root.ElementAt(section).HeaderView.View; - public virtual string GetFooterText( int section ) => _Root.ElementAt(section).FooterText; - public virtual View GetSectionFooterView( int section ) => _Root.ElementAt(section).FooterView.View; + public virtual ISectionHeader GetSectionHeaderView( int section ) => _Root.ElementAt(section).HeaderView; + public virtual string? GetFooterText( int section ) => _Root.ElementAt(section).FooterText; + public virtual ISectionFooter GetSectionFooterView( int section ) => _Root.ElementAt(section).FooterView; protected override void OnRowSelected( object item ) {