diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 74ac5ab1208a4..e08e7fbb995b4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -158,7 +158,15 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, for (size_t i = available_layer_index_; i < layers_.size(); i++) { results.push_back(layers_[i]); } - layers_.erase(layers_.begin() + available_layer_index_, layers_.end()); + // Leave at least one overlay layer, to work around cases where scrolling + // platform views under an app bar continually adds and removes an + // overlay layer. This logic could be removed if https://github.com/flutter/flutter/issues/150646 + // is fixed. + static constexpr size_t kLeakLayerCount = 1; + size_t erase_offset = std::max(available_layer_index_, kLeakLayerCount); + if (erase_offset < layers_.size()) { + layers_.erase(layers_.begin() + erase_offset, layers_.end()); + } return results; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index a14dcf8007844..32d1ed30a01cf 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -3335,10 +3335,10 @@ - (void)testLayerPool { pool.RecycleLayers(); XCTAssertEqual(pool.size(), 2u); - // Free the unused layers. + // Free the unused layers. One should remain. auto unused_layers = pool.RemoveUnusedLayers(); XCTAssertEqual(unused_layers.size(), 2u); - XCTAssertEqual(pool.size(), 0u); + XCTAssertEqual(pool.size(), 1u); } @end