dotnet/maui · error · InvalidOperationException
ViewCell must have a View
Error message
ViewCell must have a View
What it means
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.
Source
Thrown at src/Controls/src/Core/Compatibility/Handlers/ListView/iOS/ViewCellRenderer.cs:175
{
viewCell.PropertyChanged -= ViewCellPropertyChanged;
viewCell.View.MeasureInvalidated -= OnMeasureInvalidated;
SetRealCell(viewCell, null);
}
#pragma warning restore CS0618 // Type or member is obsolete
_viewCell = null;
}
_disposed = true;
base.Dispose(disposing);
}
IPlatformViewHandler GetNewRenderer()
{
#pragma warning disable CS0618 // Type or member is obsolete
if (ViewCell is not ViewCell viewCell || viewCell.View == null)
throw new InvalidOperationException($"ViewCell must have a {nameof(viewCell.View)}");
#pragma warning restore CS0618 // Type or member is obsolete
var newRenderer = viewCell.View.ToHandler(viewCell.View.FindMauiContext());
_rendererRef = new WeakReference<IPlatformViewHandler>(newRenderer);
ContentView.ClearSubviews();
ContentView.AddSubview(newRenderer.VirtualView.ToPlatform());
return (IPlatformViewHandler)newRenderer;
}
#pragma warning disable CS0618 // Type or member is obsolete
void UpdateCell(ViewCell cell)
#pragma warning restore CS0618 // Type or member is obsolete
{
#pragma warning disable CS0618 // Type or member is obsolete
if (ViewCell is ViewCell oldCell)
{
BeginInvokeOnMainThread(oldCell.SendDisappearing);
oldCell.PropertyChanged -= ViewCellPropertyChanged;View on GitHub (pinned to f377ff1c5e)
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.
Example fix
// before
listView.ItemTemplate = new DataTemplate(() => new ViewCell());
// after
listView.ItemTemplate = new DataTemplate(() =>
{
return new ViewCell { View = new StackLayout { Children = { new Label { Text = "Loading" } } } };
}); Defensive patterns
Strategy: validation
Validate before calling
static ViewCell MakeCell() =>
new ViewCell { View = new StackLayout { Children = { new Label { Text = "Loading" } } } }; Type guard
static bool HasView(ViewCell c) => c.View is not null;
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ViewCell must have a View
- Implement INativeElementView on cell renderer: {ContentCell.
- No UIViewController found to present.
- Index '{Math.Max(e.NewStartingIndex, e.OldStartingIndex)}' i
- Header cells do not support context actions
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/fd65c393dd607bf7.
Report an issue: GitHub.