.NET MAUI应用iOS端导航至部分页面时抛出UITableView错误
MAUI iOS导航至含CollectionView页面时抛出UITableView错误的排查与解决
我开发的跨Android/iOS的MAUI应用,在iOS设备(模拟器或真机)导航至StocktakingView页面时,会抛出UITableView相关错误(截图如下):
已知数据在跳转前已通过HTTP请求加载完成,通过导航参数传递到目标页面,且其他使用相同逻辑的含CollectionView页面无此问题。已尝试的修复手段包括:将CollectionView放入Grid、替换为ListView、移除CollectionView、移除OnAppearing事件,但均未解决。
开发环境:Windows Visual Studio 17.9.2,连接安装XCode 15.2的Mac,使用Community MVVM Toolkit。
相关代码片段
StocktakingView的XAML代码
<ContentPage xmlns=...> <ContentPage.Behaviors> <toolkit:EventToCommandBehavior EventName="Appearing" Command="{Binding AppearingCommand}" /> <toolkit:EventToCommandBehavior EventName="NavigatedFrom" Command="{Binding NavigatedFromCommand}" /> </ContentPage.Behaviors> <ContentPage.ToolbarItems> <ToolbarItem Command="{Binding CreateCommand}" IconImageSource="{FontImageSource FontFamily=MaterialSharp, Glyph={x:Static m:MaterialSharp.Add}, Color={AppThemeBinding Dark=White, Light=Black}}" /> </ContentPage.ToolbarItems> <CollectionView ItemsSource="{Binding Stocktakings}"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="model:Stocktaking"> <Grid ColumnDefinitions="*,*" Padding="10"> <Grid.GestureRecognizers> <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type vm:StocktakingViewModel}}, Path=TapCommand}" CommandParameter="{Binding .}" /> </Grid.GestureRecognizers> <Label Grid.Column="0" Text="{Binding Name}" FontAttributes="Bold" /> <Label Grid.Column="1" Text="{Binding Status}" /> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </ContentPage>
StocktakingViewModel代码
[QueryProperty("Stocktakings_list", "stocktakings")] public partial class StocktakingViewModel : BaseViewModel { private readonly IUserDialogs _userDialogs; private readonly IGenericService<Stocktaking, StocktakingCreationInfo> _stocktakingService; [ObservableProperty] List<Stocktaking> stocktakings_list; [ObservableProperty] ObservableCollection<Stocktaking> stocktakings; public StocktakingViewModel(IUserDialogs userDialogs, IGenericService<Stocktaking, StocktakingCreationInfo> stocktakingService) { _userDialogs = userDialogs; _stocktakingService = stocktakingService; } [RelayCommand] private void OnAppearing() { Stocktakings = new ObservableCollection<Stocktaking>(Stocktakings_list); } ...
导航跳转代码
private async Task NavigateToStocktaking() { List<Stocktaking> stocktakings = await _stocktakingService.GetAll(); Dictionary<string, object> param = new Dictionary<string, object> { { "stocktakings", stocktakings } }; await Shell.Current.GoToAsync(nameof(StocktakingView), param); }
可能的解决方向
- 移除Appearing事件依赖,改用属性变更触发集合初始化
iOS上CollectionView的渲染时机与Android存在差异,Appearing事件触发时视图可能尚未完成初始化。可以直接在Stocktakings_list属性变更时初始化绑定集合:
[ObservableProperty] List<Stocktaking> stocktakings_list; // 重写属性变更回调 partial void OnStocktakings_listChanged(List<Stocktaking> value) { if (value != null) { Stocktakings = new ObservableCollection<Stocktaking>(value); } }
同时删除OnAppearing命令中的集合初始化代码,让数据参数传递完成后自动更新UI绑定。
- 强制在UI线程执行集合更新操作
iOS对UI操作的线程要求严格,即使数据提前加载,集合初始化操作也可能意外跑在非UI线程。用MainThread包裹操作确保在UI线程执行:
[RelayCommand] private void OnAppearing() { if (Stocktakings_list != null) { MainThread.BeginInvokeOnMainThread(() => { Stocktakings = new ObservableCollection<Stocktaking>(Stocktakings_list); }); } }
- 明确CollectionView的布局约束
给CollectionView添加明确的布局属性,避免iOS上因布局异常导致UITableView渲染错误:
<ContentPage.Content> <CollectionView ItemsSource="{Binding Stocktakings}" VerticalOptions="FillAndExpand"> <!-- 现有ItemTemplate代码 --> </CollectionView> </ContentPage.Content>
- 校验导航参数传递完整性
在ViewModel的OnStocktakings_listChanged回调中添加日志,确认Stocktakings_list是否被正确赋值,排除参数传递过程中数据丢失或为空的情况。
内容的提问来源于stack exchange,提问作者Fryndorfer
相关产品推荐
相关产品推荐

