Skip to content

[iOS] - UiKitView behind a full-screen BottomSheet receives taps on iOS #176476

@Premnath2000

Description

@Premnath2000

Steps to reproduce

  1. Create a Flutter app with a CustomScrollView.

  2. Add a SliverAppBar with a UiKitView in actions (e.g., right-side circle button).

  3. Add a list below the app bar (e.g., SliverList with multiple items).

  4. Add a bottom-aligned row of multiple UiKitViews.

  5. Wrap list items with GestureDetector that shows a full-screen ModalBottomSheet (isScrollControlled: true).

  6. Run on iOS (Simulator or device).

  7. Tap the UiKitView inside the bottom sheet at a location overlapping the UiKitView behind.

Expected results

No need to listen in the bottom sheet, and some rectangular shapes(Masked UikitView) should not be shown in the bottom sheet.

Actual results

The UiKitView behind the bottom sheet also receives the tap.

Taps “pass through” the overlaying Flutter bottom sheet.

Code sample

Main dart

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SliverAppBarDemo(),
    );
  }
}

class SliverAppBarDemo extends StatelessWidget {
  const SliverAppBarDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Stack(
          children: [
            CustomScrollView(
              slivers: [
                SliverAppBar(
                  toolbarHeight: 100,
                  backgroundColor: Colors.blue,
                  centerTitle: true,
                  floating: false,
                  pinned: false,
                  expandedHeight: 70,
                  leading: const SizedBox(width: 50),
                  title: const Text(
                    "Header Title",
                    style: TextStyle(
                      fontSize: 18,
                      color: Colors.white,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  actions: [
                    Container(
                      margin: const EdgeInsets.only(right: 12),
                      width: 50,
                      height: 50,
                      color: Colors.red,
                      child: UiKitView(
                        key: const ValueKey('plusButton_glass_view'),
                        viewType: "circle_container_view",
                        creationParamsCodec: const StandardMessageCodec(),
                      ),
                    ),
                  ],
                ),
                SliverPadding(
                  padding: const EdgeInsetsDirectional.only(bottom: 80),
                  sliver: SliverList(
                    delegate: SliverChildBuilderDelegate(
                          (context, index) {
                        return GestureDetector(
                          onTap: () {
                            showModalBottomSheet(
                              useSafeArea: true,
                              context: context,
                              isScrollControlled: true, // makes full screen
                              backgroundColor: Colors.amber.shade50,
                              builder: (context) {
                                return SizedBox(
                                  height: MediaQuery.of(context).size.height, // full height
                                  child: Column(
                                    children: [
                                      AppBar(
                                        automaticallyImplyLeading: false,
                                        title: Text("Item $index Details"),
                                        backgroundColor: Colors.blue,
                                      ),
                                      Expanded(
                                        child: Center(
                                          child: Text(
                                            "Full bottom sheet content for Item $index",
                                            style: const TextStyle(fontSize: 18),
                                          ),
                                        ),
                                      ),
                                    ],
                                  ),
                                );
                              },
                            );
                          },
                          child: Container(
                            height: 50,
                            alignment: Alignment.centerLeft,
                            padding: const EdgeInsets.symmetric(horizontal: 16),
                            color: index.isEven ? Colors.grey[200] : Colors.white,
                            child: Text("Item $index"),
                          ),
                        );
                      },
                      childCount: 50,
                    ),
                  ),
                ),

                // SliverPadding(
                //   padding: const EdgeInsetsDirectional.only(bottom: 80),
                //   sliver: SliverList(
                //     delegate: SliverChildBuilderDelegate((context, index) {
                //       return Column(
                //         crossAxisAlignment: CrossAxisAlignment.start,
                //         children: [
                //           Container(
                //             height: 50,
                //             alignment: Alignment.centerLeft,
                //             padding: const EdgeInsets.symmetric(horizontal: 16),
                //             color: index.isEven ? Colors.grey[200] : Colors.white,
                //             child: Text("Item $index"),
                //           ),
                //         ],
                //       );
                //     }, childCount: 50),
                //   ),
                // ),
              ],
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Container(
                color: Colors.pink,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      margin: const EdgeInsets.only(right: 24),
                      width: 50,
                      height: 50,
                      color: Colors.orange,
                      child: UiKitView(
                        key: const ValueKey('plusButton_glass_view'),
                        viewType: "circle_container_view",
                        creationParamsCodec: const StandardMessageCodec(),
                      ),
                    ),
                    Container(
                      margin: const EdgeInsets.only(right: 24),
                      width: 50,
                      height: 50,
                      color: Colors.teal,
                      child: UiKitView(
                        key: const ValueKey('plusButton_glass_view'),
                        viewType: "circle_container_view",
                        creationParamsCodec: const StandardMessageCodec(),
                      ),
                    ),
                    Container(
                      margin: const EdgeInsets.only(right: 24),
                      width: 50,
                      height: 50,
                      color: Colors.greenAccent,
                      child: UiKitView(
                        key: const ValueKey('plusButton_glass_view'),
                        viewType: "circle_container_view",
                        creationParamsCodec: const StandardMessageCodec(),
                      ),
                    ),
                  ],

                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

AppDelgate

import Flutter
import UIKit

@main
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
      let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
           let factory = PlusButtonViewFactory()
           registrar(forPlugin: "circle_container_view_plugin")?
               .register(factory, withId: "circle_container_view")
      
      
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

ButtonCode

class PlusButtonViewFactory: NSObject, FlutterPlatformViewFactory {
    func create(
        withFrame frame: CGRect,
        viewIdentifier viewId: Int64,
        arguments args: Any?
    ) -> FlutterPlatformView {
        return SwiftUIViewWrapper(rootView: PlusButtonView(), frame: frame)

    }
}

class SwiftUIViewWrapper: NSObject, FlutterPlatformView {
    private var hostingController: UIHostingController<AnyView>

    init<T: View>(rootView: T, frame: CGRect) {
        hostingController = UIHostingController(rootView: AnyView(rootView))
        hostingController.view.frame = frame
        hostingController.view.backgroundColor = .clear
    }

    func view() -> UIView {
        return hostingController.view
    }
}
struct PlusButtonView: View {

    var body: some View {
        if #available(iOS 26.0, *) {
            GlassEffectContainer {

                Button(action: {}) {
                    Image(systemName: "plus")
                        .font(.system(size: 20)) // Increase icon size directly
                        .frame(width: 24, height: 24)
                        .foregroundColor( .white)
                        .padding()
                }
                .frame(width: 48, height: 48)
                .background(
                  Color(hex: 0xFF15_8C5B)
                )
                .clipShape(Circle())
                .glassEffect(
                    .regular.interactive()
                )
            }

        } else {
            // Fallback on earlier versions
        }
    }
}

extension Color {
    init(hex: Int, opacity: Double = 1) {
        self.init(
            .sRGB,
            red: Double((hex >> 16) & 0xff) / 255,
            green: Double((hex >> 08) & 0xff) / 255,
            blue: Double((hex >> 00) & 0xff) / 255,
            opacity: opacity
        )
    }
}

Screenshots or Video

bottomSheetOverlay.issued.mov

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 3.37.0-0.1.pre, on macOS 26.0.1 25A362 darwin-arm64, locale en-IN)
[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 26.0)
[✓] Chrome - develop for the web
[✓] Connected device (4 available)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: platform-viewsEmbedding Android/iOS views in Flutter appscustomer: silverf: scrollingViewports, list views, slivers, etc.found in release: 3.35Found to occur in 3.35found in release: 3.37Found to occur in 3.37frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-iosiOS applications specificallyteam-iosOwned by iOS platform teamtriaged-iosTriaged by iOS platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions