{"record":{"id":"fd65c393dd607bf7","repo":"dotnet/maui","slug":"viewcell-must-have-a-view-fd65c3","errorCode":null,"errorMessage":"ViewCell must have a View","messagePattern":"ViewCell must have a View","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/Compatibility/Handlers/ListView/iOS/ViewCellRenderer.cs","lineNumber":175,"sourceCode":"\t\t\t\t\t{\n\t\t\t\t\t\tviewCell.PropertyChanged -= ViewCellPropertyChanged;\n\t\t\t\t\t\tviewCell.View.MeasureInvalidated -= OnMeasureInvalidated;\n\t\t\t\t\t\tSetRealCell(viewCell, null);\n\t\t\t\t\t}\n#pragma warning restore CS0618 // Type or member is obsolete\n\t\t\t\t\t_viewCell = null;\n\t\t\t\t}\n\n\t\t\t\t_disposed = true;\n\n\t\t\t\tbase.Dispose(disposing);\n\t\t\t}\n\n\t\t\tIPlatformViewHandler GetNewRenderer()\n\t\t\t{\n#pragma warning disable CS0618 // Type or member is obsolete\n\t\t\t\tif (ViewCell is not ViewCell viewCell || viewCell.View == null)\n\t\t\t\t\tthrow new InvalidOperationException($\"ViewCell must have a {nameof(viewCell.View)}\");\n#pragma warning restore CS0618 // Type or member is obsolete\n\n\t\t\t\tvar newRenderer = viewCell.View.ToHandler(viewCell.View.FindMauiContext());\n\t\t\t\t_rendererRef = new WeakReference<IPlatformViewHandler>(newRenderer);\n\t\t\t\tContentView.ClearSubviews();\n\t\t\t\tContentView.AddSubview(newRenderer.VirtualView.ToPlatform());\n\t\t\t\treturn (IPlatformViewHandler)newRenderer;\n\t\t\t}\n\n#pragma warning disable CS0618 // Type or member is obsolete\n\t\t\tvoid UpdateCell(ViewCell cell)\n#pragma warning restore CS0618 // Type or member is obsolete\n\t\t\t{\n#pragma warning disable CS0618 // Type or member is obsolete\n\t\t\t\tif (ViewCell is ViewCell oldCell)\n\t\t\t\t{\n\t\t\t\t\tBeginInvokeOnMainThread(oldCell.SendDisappearing);\n\t\t\t\t\toldCell.PropertyChanged -= ViewCellPropertyChanged;","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/Compatibility/Handlers/ListView/iOS/ViewCellRenderer.cs#L157-L193","documentation":"Thrown by the iOS ViewCellRenderer.GetNewRenderer when ViewCell.View is null at render time. The iOS renderer, like its Android counterpart, requires a non-null child View to create a platform handler and layout the cell.","triggerScenarios":"A ViewCell with no View child. View set to null during/after recycling. A DataTemplate returning a ViewCell whose View is populated asynchronously and not yet set when the renderer requests a new handler.","commonSituations":"Empty <ViewCell/> in a GroupHeaderTemplate or ItemTemplate. Lazy/async View population that has not completed by measure time. Conditional code that fails to assign View on some path.","solutions":["Always assign a non-null View synchronously in the DataTemplate factory / cell construction.","Use a placeholder View and update it later if content loads asynchronously.","Validate the cell has a View before it enters the list's measurement cycle."],"exampleFix":"// before\nlistView.ItemTemplate = new DataTemplate(() => new ViewCell());\n\n// after\nlistView.ItemTemplate = new DataTemplate(() =>\n{\n    return new ViewCell { View = new StackLayout { Children = { new Label { Text = \"Loading\" } } } };\n});","handlingStrategy":"validation","validationCode":"static ViewCell MakeCell() =>\n    new ViewCell { View = new StackLayout { Children = { new Label { Text = \"Loading\" } } } };","typeGuard":"static bool HasView(ViewCell c) => c.View is not null;","tryCatchPattern":null,"preventionTips":["Always assign a non-null View synchronously when constructing the cell.","Use a placeholder View and swap content after async load.","Validate cells before they enter the list measurement cycle."],"tags":["maui","listview","ios","viewcell","null"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}