Skip to content

Commit e89d243

Browse files
authored
Merge pull request #50 from zleao/copilot/fix-49
[MacCatalyst] Implement missing features - ItemTemplate support and text handling fixes
2 parents 5678794 + 3d11c5f commit e89d243

File tree

8 files changed

+227
-162
lines changed

8 files changed

+227
-162
lines changed

sample/AutoCompleteEntry.Sample/AutoCompleteEntry.Sample.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
2424
<ApplicationVersion>1</ApplicationVersion>
2525

26-
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
27-
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
26+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
27+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
2828
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
2929
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
3030
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>

src/AutoCompleteEntry/AutoCompleteEntry.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<SingleProject>true</SingleProject>
77
<ImplicitUsings>enable</ImplicitUsings>
88
<AssemblyName>zoft.MauiExtensions.Controls.AutoCompleteEntry</AssemblyName>
9-
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
10-
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.2</SupportedOSPlatformVersion>
9+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
10+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
1111
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
1212
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
1313
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>

src/AutoCompleteEntry/Platforms/MacCatalyst/AutoCompleteEntryExtensions.cs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Foundation;
1+
using Foundation;
22
using Microsoft.Maui.Platform;
33
using UIKit;
44
using zoft.MauiExtensions.Core.Extensions;
@@ -15,11 +15,12 @@ public static class AutoCompleteEntryExtensions
1515
/// </summary>
1616
/// <param name="iosAutoCompleteEntry"></param>
1717
/// <param name="autoCompleteEntry"></param>
18-
public static void UpdateDisplayMemberPath(this IOSAutoCompleteEntry iosAutoCompleteEntry, AutoCompleteEntry autoCompleteEntry)
18+
public static void UpdateDisplayMemberPath(this IOSAutoCompleteEntry iosAutoCompleteEntry, AutoCompleteEntry autoCompleteEntry, IMauiContext mauiContext)
1919
{
2020
iosAutoCompleteEntry.SetItems(autoCompleteEntry.ItemsSource,
21-
(o) => !string.IsNullOrEmpty(autoCompleteEntry?.DisplayMemberPath) ? o.GetPropertyValueAsString(autoCompleteEntry?.DisplayMemberPath) : o?.ToString(),
22-
(o) => !string.IsNullOrEmpty(autoCompleteEntry?.TextMemberPath) ? o.GetPropertyValueAsString(autoCompleteEntry?.TextMemberPath) : o?.ToString());
21+
autoCompleteEntry?.DisplayMemberPath,
22+
(o) => !string.IsNullOrEmpty(autoCompleteEntry?.TextMemberPath) ? o.GetPropertyValueAsString(autoCompleteEntry?.TextMemberPath) : o?.ToString(),
23+
mauiContext);
2324
}
2425

2526
/// <summary>
@@ -57,11 +58,12 @@ public static void UpdateIsTextPredictionEnabled(this IOSAutoCompleteEntry iosAu
5758
/// </summary>
5859
/// <param name="iosAutoCompleteEntry"></param>
5960
/// <param name="autoCompleteEntry"></param>
60-
public static void UpdateItemsSource(this IOSAutoCompleteEntry iosAutoCompleteEntry, AutoCompleteEntry autoCompleteEntry)
61+
public static void UpdateItemsSource(this IOSAutoCompleteEntry iosAutoCompleteEntry, AutoCompleteEntry autoCompleteEntry, IMauiContext mauiContext)
6162
{
6263
iosAutoCompleteEntry.SetItems(autoCompleteEntry?.ItemsSource,
63-
(o) => !string.IsNullOrEmpty(autoCompleteEntry?.DisplayMemberPath) ? o.GetPropertyValueAsString(autoCompleteEntry?.DisplayMemberPath) : o?.ToString(),
64-
(o) => !string.IsNullOrEmpty(autoCompleteEntry?.TextMemberPath) ? o.GetPropertyValueAsString(autoCompleteEntry?.TextMemberPath) : o?.ToString());
64+
autoCompleteEntry?.DisplayMemberPath,
65+
(o) => !string.IsNullOrEmpty(autoCompleteEntry?.TextMemberPath) ? o.GetPropertyValueAsString(autoCompleteEntry?.TextMemberPath) : o?.ToString(),
66+
mauiContext);
6567
}
6668

6769
/// <summary>
@@ -120,8 +122,16 @@ public static void UpdateReturnType(this IOSAutoCompleteEntry iosAutoCompleteEnt
120122
/// <param name="autoCompleteEntry"></param>
121123
public static void UpdateSelectedSuggestion(this IOSAutoCompleteEntry iosAutoCompleteEntry, AutoCompleteEntry autoCompleteEntry)
122124
{
123-
var o = autoCompleteEntry.SelectedSuggestion;
124-
iosAutoCompleteEntry.Text = !string.IsNullOrEmpty(autoCompleteEntry.TextMemberPath) ? o.GetPropertyValueAsString(autoCompleteEntry.TextMemberPath) : o?.ToString();
125+
if (autoCompleteEntry.SelectedSuggestion is null)
126+
{
127+
return;
128+
}
129+
130+
iosAutoCompleteEntry.Text =
131+
!string.IsNullOrEmpty(autoCompleteEntry.TextMemberPath) ?
132+
autoCompleteEntry.SelectedSuggestion.GetPropertyValueAsString(autoCompleteEntry.TextMemberPath)
133+
:
134+
autoCompleteEntry.SelectedSuggestion.ToString();
125135
}
126136

127137
/// <summary>
@@ -162,8 +172,8 @@ public static void UpdateShowBottomBorder(this IOSAutoCompleteEntry iosAutoCompl
162172
/// </summary>
163173
/// <param name="platformView"></param>
164174
/// <param name="virtualView"></param>
165-
public static void UpdateItemTemplate(this IOSAutoCompleteEntry platformView, AutoCompleteEntry virtualView)
175+
public static void UpdateItemTemplate(this IOSAutoCompleteEntry iosAutoCompleteEntry, AutoCompleteEntry autoCompleteEntry)
166176
{
167-
//TODO: Implement ItemTemplate handling
177+
iosAutoCompleteEntry.ItemTemplate = autoCompleteEntry.ItemTemplate;
168178
}
169179
}

src/AutoCompleteEntry/Platforms/MacCatalyst/AutoCompleteEntryHandler.cs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,6 @@ public partial class AutoCompleteEntryHandler : ViewHandler<AutoCompleteEntry, I
1010
/// <inheritdoc/>
1111
protected override IOSAutoCompleteEntry CreatePlatformView() => new();
1212

13-
/// <inheritdoc/>
14-
public override Size GetDesiredSize(double widthConstraint, double heightConstraint)
15-
{
16-
if (double.IsInfinity(widthConstraint) || double.IsInfinity(heightConstraint))
17-
{
18-
PlatformView.InputTextField.SizeToFit();
19-
return new Size(PlatformView.InputTextField.Frame.Width, PlatformView.InputTextField.Frame.Height);
20-
}
21-
22-
return base.GetDesiredSize(widthConstraint, heightConstraint);
23-
}
24-
2513
/// <inheritdoc/>
2614
protected override void ConnectHandler(IOSAutoCompleteEntry platformView)
2715
{
@@ -82,11 +70,11 @@ private void PlatformView_OnLoaded(object sender, EventArgs e)
8270
PlatformView.InputTextField.UpdateHorizontalTextAlignment(VirtualView);
8371
PlatformView.UpdateMaxLength(VirtualView);
8472
PlatformView.UpdateIsReadOnly(VirtualView);
85-
PlatformView.UpdateDisplayMemberPath(VirtualView);
73+
PlatformView.UpdateDisplayMemberPath(VirtualView, MauiContext);
8674
PlatformView.UpdateIsEnabled(VirtualView);
8775
PlatformView.UpdateUpdateTextOnSelect(VirtualView);
8876
PlatformView.UpdateIsSuggestionListOpen(VirtualView);
89-
PlatformView.UpdateItemsSource(VirtualView);
77+
PlatformView.UpdateItemsSource(VirtualView, MauiContext);
9078
}
9179

9280
private void PlatformView_OnShouldReturn(object sender, EventArgs e)
@@ -113,6 +101,7 @@ private void PlatformView_OnTextChanged(object sender, AutoCompleteEntryTextChan
113101
public static void MapBackground(IAutoCompleteEntryHandler handler, IEntry entry)
114102
{
115103
handler.PlatformView?.InputTextField.UpdateBackground(entry);
104+
handler.PlatformView?.UpdateBackground(entry);
116105
}
117106

118107
/// <summary>
@@ -152,7 +141,7 @@ public static void MapCursorPosition(IAutoCompleteEntryHandler handler, IEntry e
152141
/// <param name="autoCompleteEntry"></param>
153142
public static void MapDisplayMemberPath(IAutoCompleteEntryHandler handler, AutoCompleteEntry autoCompleteEntry)
154143
{
155-
handler?.PlatformView?.UpdateDisplayMemberPath(autoCompleteEntry);
144+
handler?.PlatformView?.UpdateDisplayMemberPath(autoCompleteEntry, handler.MauiContext);
156145
}
157146

158147
/// <summary>
@@ -230,7 +219,7 @@ public static void MapIsTextPredictionEnabled(IAutoCompleteEntryHandler handler,
230219
/// <param name="autoCompleteEntry"></param>
231220
public static void MapItemsSource(IAutoCompleteEntryHandler handler, AutoCompleteEntry autoCompleteEntry)
232221
{
233-
handler?.PlatformView?.UpdateItemsSource(autoCompleteEntry);
222+
handler?.PlatformView?.UpdateItemsSource(autoCompleteEntry, handler.MauiContext);
234223
}
235224

236225
/// <summary>
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
using Foundation;
2+
using Microsoft.Maui.Controls.Internals;
3+
using Microsoft.Maui.Platform;
4+
using System.Collections;
5+
using System.Collections.Specialized;
6+
using UIKit;
7+
8+
namespace zoft.MauiExtensions.Controls.Platform;
9+
10+
internal class AutoCompleteEntryTableSource : UITableViewSource
11+
{
12+
private readonly UITableView _view;
13+
private readonly IList _items;
14+
private readonly string _displayMemberPath;
15+
private readonly DataTemplate _itemTemplate;
16+
private readonly IMauiContext _mauiContext;
17+
18+
//private readonly string _cellIdentifier;
19+
private readonly Page _listViewContainer;
20+
21+
private DataTemplate _defaultItemTemplate;
22+
internal DataTemplate DefaultItemTemplate
23+
{
24+
get
25+
{
26+
if (_defaultItemTemplate == null)
27+
{
28+
_defaultItemTemplate = new DataTemplate(() =>
29+
{
30+
var label = new Label();
31+
32+
label.SetBinding(Label.TextProperty, _displayMemberPath ?? ".");
33+
label.HorizontalTextAlignment = Microsoft.Maui.TextAlignment.Center;
34+
label.VerticalTextAlignment = Microsoft.Maui.TextAlignment.Center;
35+
label.MinimumHeightRequest = 35;
36+
37+
return label;
38+
});
39+
}
40+
41+
return _defaultItemTemplate;
42+
}
43+
}
44+
45+
public AutoCompleteEntryTableSource(UITableView view, IList items, string displayMemberPath, DataTemplate itemTemplate, IMauiContext mauiContext)
46+
{
47+
_view = view;
48+
_items = items;
49+
_displayMemberPath = displayMemberPath;
50+
_itemTemplate = itemTemplate;
51+
_mauiContext = mauiContext;
52+
//_cellIdentifier = Guid.NewGuid().ToString();
53+
_listViewContainer = Application.Current.Windows[0].Page;
54+
55+
CheckIfItemsSourceIsNotifiable();
56+
}
57+
58+
private void CheckIfItemsSourceIsNotifiable()
59+
{
60+
if (_items is INotifyCollectionChanged notifiableItems)
61+
{
62+
notifiableItems.CollectionChanged += NotifiableItems_CollectionChanged;
63+
}
64+
}
65+
66+
private void NotifiableItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
67+
{
68+
if (!MainThread.IsMainThread)
69+
{
70+
MainThread.BeginInvokeOnMainThread(() => CollectionChanged(e));
71+
}
72+
else
73+
{
74+
CollectionChanged(e);
75+
}
76+
}
77+
78+
private void CollectionChanged(NotifyCollectionChangedEventArgs args)
79+
{
80+
_view.ReloadData();
81+
}
82+
83+
protected override void Dispose(bool disposing)
84+
{
85+
base.Dispose(disposing);
86+
87+
if (disposing && _items is INotifyCollectionChanged notifiableItems)
88+
{
89+
notifiableItems.CollectionChanged -= NotifiableItems_CollectionChanged;
90+
}
91+
}
92+
93+
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
94+
{
95+
var item = _items[indexPath.Row];
96+
var templateToUse = _itemTemplate ?? DefaultItemTemplate;
97+
98+
var cellId = ((IDataTemplateController)templateToUse.SelectDataTemplate(item, _listViewContainer)).IdString;
99+
100+
var cell = tableView.DequeueReusableCell(cellId) ?? new UITableViewCell(UITableViewCellStyle.Default, cellId);
101+
102+
// Create the MAUI view from the DataTemplate
103+
var templateView = templateToUse.CreateContent() as View;
104+
templateView.BindingContext = item;
105+
106+
// Convert MAUI view to native iOS view with proper MauiContext
107+
var nativeView = templateView.ToPlatform(_mauiContext);
108+
109+
// Clear previous content to avoid overlapping
110+
foreach (var subview in cell.ContentView.Subviews)
111+
{
112+
subview.RemoveFromSuperview();
113+
}
114+
115+
nativeView.Frame = cell.ContentView.Bounds;
116+
nativeView.AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;
117+
118+
cell.ContentView.AddSubview(nativeView);
119+
120+
return cell;
121+
}
122+
123+
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
124+
{
125+
OnTableRowSelected(indexPath);
126+
}
127+
128+
public override nint RowsInSection(UITableView tableview, nint section)
129+
{
130+
return _items.Count;
131+
}
132+
133+
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
134+
{
135+
return 35f;
136+
}
137+
138+
public event EventHandler<TableRowSelectedEventArgs<object>> TableRowSelected;
139+
140+
private void OnTableRowSelected(NSIndexPath itemIndexPath)
141+
{
142+
var item = _items[itemIndexPath.Row];
143+
TableRowSelected?.Invoke(this, new TableRowSelectedEventArgs<object>(item, itemIndexPath));
144+
}
145+
}

0 commit comments

Comments
 (0)