ios_adaptive_context_menu

Flutter plugin for showing adaptive single-tap context menus on iOS and Android.

Features

  • Opens the iOS system context menu with a single tap.
  • Opens a Material popup context menu on Android with the same API.
  • Supports actions, dividers, and nested submenus.
  • Supports SF Symbols (iconSystemName) and SVG asset icons (iconAssetPath).
  • Uses a unified action model across iOS and Android.

Requirements

  • Flutter >=3.13.0
  • iOS 14.0+

Installation

dependencies:
  ios_adaptive_context_menu: ^0.1.0

Run Example App

cd example
flutter pub get
flutter run -d ios

Usage

import 'package:flutter/material.dart';
import 'package:ios_adaptive_context_menu/ios_adaptive_context_menu.dart';

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

  @override
  Widget build(BuildContext context) {
    return IosSingleTapContextMenu(
      actions: const [
        IosContextMenuAction(
          id: 'share',
          title: 'Share',
          iconSystemName: 'square.and.arrow.up',
        ),
        IosContextMenuDivider(),
        IosContextMenuAction(
          id: 'delete',
          title: 'Delete',
          iconSystemName: 'trash',
          destructive: true,
        ),
      ],
      onSelected: (id) {
        debugPrint('Selected action: $id');
      },
      child: const ListTile(
        title: Text('Tap me'),
        subtitle: Text('Shows iOS native context menu'),
      ),
    );
  }
}

API

  • IosSingleTapContextMenu
  • IosContextMenuAction
  • IosContextMenuDivider
  • IosContextMenuSubmenu

Why this approach is stable in Flutter UI

When UIKit content is kept permanently embedded in the Flutter view hierarchy, it can cause rendering and interaction issues in some layouts.

This package avoids that by using an on-demand native bridge:

  • The user taps a Flutter widget.
  • The tap is forwarded to native iOS code.
  • Native creates a temporary invisible UIKit anchor (UIButton) only for menu presentation.
  • The system context menu is shown from that temporary anchor.
  • The anchor is cleaned up after selection/dismissal (and also on widget dispose).

Because no persistent UIKit view is mounted inside Flutter for normal rendering, this approach prevents common Flutter UI breakage caused by long-lived UIKit embedding.

Screenshots

iOS Android
iOS screenshot Android screenshot

Libraries

ios_adaptive_context_menu
Public package entrypoint for the adaptive single-tap context menu plugin.
ios_single_tap_context_menu
Adaptive single-tap context menu widgets and models for iOS and Android.