在 .net Maui iOS ObjCRuntime.ObjCException 中更改视图时出错

问题描述 投票:0回答:1

我正在尝试创建一种包含多个问题的表单,问题是每个视图中都有一个问题,当移动到下一个视图时,当我的问题类型相同时,问题类型可能会也可能不会改变作为下一个我启动相同的视图,在 Android 中它允许,但在 iOS 中我遇到以下问题:

ObjCRuntime.ObjCException
  Message = Objective-C exception thrown.  Name: NSInvalidArgumentException Reason: <Microsoft_Maui_Controls_Platform_Compatibility_ShellSectionRenderer: 0x116f56800> is pushing the same view controller instance (<Microsoft_Maui_Platform_PageViewController: 0x117869db0>) more than once which is not supported and is most likely an error in the application : com.geicam.asociados
Native stack trace:
    0   CoreFoundation                      0x00000001804ae0f8 __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x0000000180087db4 objc_exception_throw + 56
    2   UIKitCore                           0x0000000184bf9334 -[UINavigationController pushViewController:transition:forceImmediate:] + 3736
    3   UIKitCore                           0x0000000184bf832c -[UINavigationController pushViewController:animated:] + 756
    4   libxamarin-dotnet-debug.dylib       0x0000000107f94bd4 xamarin_dyn_objc_msgSendSuper + 164
    5   geicam.asociados                    0x000000010589d95c interp_to_native_trampoline + 156
    6   libmonosgen-2.0.dylib               0x00000001086ff6f8 ves_pinvoke_method + 584
    7   libmonosgen-2.0.dylib               0x00000001086f3e84 mono_interp_exec_method + 3052
    8   libmonosgen-2.0.dylib               0x00000001086f194c interp_runtime_invoke + 244
    9   libmonosgen-2.0.dylib               0x000000010860abf0 mono_jit_runtime_invoke + 1116
    10  libmonosgen-2.0.dylib               0x00000001087c6cb0 mono_runtime_try_invoke + 156
    11  libmonosgen-2.0.dylib               0x00000001087c9d28 mono_runtime_invoke + 488
    12  geicam.asociados                    0x00000001058bf400 _ZL30native_to_managed_trampoline_9P11objc_objectP13objc_selectorPP11_MonoMethodj + 316
    13  geicam.asociados                    0x00000001059103bc -[UIKit_UIControlEventProxy BridgeSelector] + 44
    14  UIKitCore                           0x00000001853d58ec -[UIApplication sendAction:to:from:forEvent:] + 96
    15  UIKitCore                           0x0000000184ce23d0 -[UIControl sendAction:to:forEvent:] + 108
    16  UIKitCore                           0x0000000184ce2714 -[UIControl _sendActionsForEvents:withEvent:] + 268
    17  UIKitCore                           0x0000000184cdf188 -[UIButton _sendActionsForEvents:withEvent:] + 120
    18  UIKitCore                           0x0000000184ce13ac -[UIControl touchesEnded:withEvent:] + 392
    19  UIKitCore                           0x0000000185409354 -[UIWindow _sendTouchesForEvent:] + 900
    20  UIKitCore                           0x000000018540a878 -[UIWindow sendEvent:] + 3104
    21  UIKitCore                           0x00000001853ea238 -[UIApplication sendEvent:] + 580
    22  UIKitCore                           0x000000018546dff4 __dispatchPreprocessedEventFromEventQueue + 1684
    23  UIKitCore                           0x0000000185470e90 __processEventQueue + 5604
    24  UIKitCore                           0x00000001854697f0 __eventFetcherSourceCallback + 160
    25  CoreFoundation                      0x000000018040ee48 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    26  CoreFoundation                      0x000000018040ed90 __CFRunLoopDoSource0 + 172
    27  CoreFoundation                      0x000000018040e500 __CFRunLoopDoSources0 + 232
    28  CoreFoundation                      0x0000000180408be8 __CFRunLoopRun + 768
    29  CoreFoundation                      0x00000001804084d4 CFRunLoopRunSpecific + 572
    30  GraphicsServices                    0x000000018ef2aae4 GSEventRunModal + 160
    31  UIKitCore                           0x00000001853d0a28 -[UIApplication _run] + 868
    32  UIKitCore                           0x00000001853d46b0 UIApplicationMain + 124
    33  libxamarin-dotnet-debug.dylib       0x0000000107f4fa84 xamarin_UIApplicationMain + 60
    34  libmonosgen-2.0.dylib               0x0000000108700abc do_icall + 316
    35  libmonosgen-2.0.dylib               0x00000001086ff35c do_icall_wrapper + 356
    36  libmonosgen-2.0.dylib               0x00000001086f3dac mono_interp_exec_method + 2836
    37  libmonosgen-2.0.dylib               0x00000001086f194c interp_runtime_invoke + 244
    38  libmonosgen-2.0.dylib               0x000000010860abf0 mono_jit_runtime_invoke + 1116
    39  libmonosgen-2.0.dylib               0x00000001087c5c9c mono_runtime_invoke_checked + 148
    40  libmonosgen-2.0.dylib               0x00000001087cd27c mono_runtime_exec_main_checked + 116
    41  libmonosgen-2.0.dylib               0x000000010865ee78 mono_jit_exec + 364
    42  libxamarin-dotnet-debug.dylib       0x0000000107f93a38 xamarin_main + 2320
    43  geicam.asociados                    0x0000000105981560 main + 72
    44  dyld                                0x000000010654d544 start_sim + 20
    45  ???                                 0x0000000106652154 0x0 + 4402258260
    46  ???                                 0xb162800000000000 0x0 + 12781919429919244288

  Origin = Microsoft.iOS

每当您按下下一步按钮时,它都会执行以下功能:

public async void CargarView(int id)
{

    switch ((enumFormTipoPregunta)id)
    {
        case enumFormTipoPregunta.TextoCorto:
            var navigationTextoCorto = new Dictionary<string, object>
            {
                 { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaTCortoView)}", navigationTextoCorto);
            break;
        case enumFormTipoPregunta.Parrafo:
            var navigationParrafo = new Dictionary<string, object>
            {
                 { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaTLargoView)}", navigationParrafo);
            break;
        case enumFormTipoPregunta.Opcion:
            var navigationParameter = new Dictionary<string, object>
            {
                 { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaOpcionView)}", navigationParameter);
            break;
        case enumFormTipoPregunta.Multiple:
            var navigationFormulario = new Dictionary<string, object>
            {
                { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaMultipleView)}", navigationFormulario);
            break;
        case enumFormTipoPregunta.Desplegable:
            var navigationDesplegable = new Dictionary<string, object>
            {
                { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaOpcionView)}", navigationDesplegable);
            break;
        case enumFormTipoPregunta.Multiple2Col:
            var navigationMultiple2Col = new Dictionary<string, object>
            {
                { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaMultipleView)}", navigationMultiple2Col);
            break;
        case enumFormTipoPregunta.Numerico:
            var navigationNumerico = new Dictionary<string, object>
            {
                { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaNumericaView)}", navigationNumerico);
            break;
        case enumFormTipoPregunta.Valoracion:
            var navigationValoracion = new Dictionary<string, object>
            {
                { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaValoracionView)}", navigationValoracion);
            break;
        case enumFormTipoPregunta.Fecha:
            var navigationFecha = new Dictionary<string, object>
            {
                { "Formulario", formul },
                { "Contador", cfo },
                { "Respuesta", gRespu }
            };
            await Shell.Current.GoToAsync($"{nameof(PreguntaFechaView)}", navigationFecha);
            break;
        default:
            break;
    }
}

我一直在做一些研究,问题是 iOS 不允许你启动相同的视图。 那么知道如何更改它以便它可以在两种设备上运行吗?

c# ios view maui
1个回答
0
投票

您可以使用 DataTemplateSelector 来更改视图:

创建模型

namespace MauiApp2.Model
{
    public class Question
    {
        public string? QuestionText { get; set; }
        public string? QuestionType { get; set; } // e.g., "Text", "MultipleChoice", etc.
        public List<string>? Options { get; set; } // For multiple choice questions
    }
}

然后查看模型

namespace MauiApp2.VieModel
{
    public class QuestionsViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<Question> Questions { get; set; }
        public QuestionsViewModel()
        {
            CreateQuestions();
        }
 
        void CreateQuestions()
        {
            Questions = new ObservableCollection<Question>
            {
                new Question() { QuestionText = "What's your name?", QuestionType = "Text" },
                new Question() { QuestionText = "Your hobbies", QuestionType = "MultipleChoice", Options=new List<string>(){"Game", "Photography", "Cycling" } },
                new Question() { QuestionText = "How old are you?", QuestionType = "Text" },
                new Question() { QuestionText = "Your favourite foods ", QuestionType = "MultipleChoice",Options=new List<string>(){"Beef", "Hamburger", "Salad" } }
            };
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

创建数据模板选择器

namespace MauiApp2
{
    public class QuestionTemplateSelector : DataTemplateSelector
    {
        public DataTemplate TextQuestionTemplate { get; set; }
        public DataTemplate MultipleChoiceQuestionTemplate { get; set; }
 
        protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
        {
            var question = item as Question;
            switch (question?.QuestionType)
            {
                case "Text":
                    return TextQuestionTemplate;
 
                case "MultipleChoice":
                    return MultipleChoiceQuestionTemplate;
 
                default:
                    return null;
            }
        }
    }
}

在主页中使用它们

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:MauiApp2.VieModel"
             xmlns:local="clr-namespace:MauiApp2"
             x:Class="MauiApp2.MainPage">
   <ContentPage.BindingContext>
       <vm:QuestionsViewModel/>
   </ContentPage.BindingContext>
   <ContentPage.Resources>
       <DataTemplate x:Key="textQuestionTemplate">
           <StackLayout>
               <Frame HasShadow="True"
                       BorderColor="DarkGray"
                       CornerRadius="5"
                       Margin="20"
                       HeightRequest="300"
                       HorizontalOptions="Center"
                       VerticalOptions="CenterAndExpand">
                   <StackLayout>
                       <Label Text="{Binding QuestionText}" />
                       <Entry Placeholder="Enter your answer here" />
                   </StackLayout>
               </Frame>
           </StackLayout>
       </DataTemplate>
       <DataTemplate x:Key="multipleChoiceQuestionTemplate">
           <StackLayout>
               <Frame HasShadow="True"
                       BorderColor="DarkGray"
                       CornerRadius="5"
                       Margin="20"
                       HeightRequest="300"
                       HorizontalOptions="Center"
                       VerticalOptions="CenterAndExpand">
                   <StackLayout>
                       <Label Text="{Binding QuestionText}" />
                       <ListView ItemsSource="{Binding Options}" />
                   </StackLayout>
               </Frame>
           </StackLayout>
       </DataTemplate>
       <local:QuestionTemplateSelector x:Key="questionTemplateSelector"
                                            TextQuestionTemplate="{StaticResource textQuestionTemplate}"
                                            MultipleChoiceQuestionTemplate="{StaticResource multipleChoiceQuestionTemplate}"/>
   </ContentPage.Resources>
   <StackLayout Margin="20">
       <CarouselView ItemsSource="{Binding Questions}"
                      IndicatorView="indicatorView"
                      ItemTemplate="{StaticResource questionTemplateSelector}" />
       <IndicatorView x:Name="indicatorView"
                       IndicatorColor="LightGray"
                       SelectedIndicatorColor="DarkGray"
                       HorizontalOptions="Center" />
   </StackLayout>
</ContentPage>

希望可以帮到你!

© www.soinside.com 2019 - 2024. All rights reserved.