Skip to content

Aeastr/MenuWithAView

MenuWithAView Logo

MenuWithAView

MenuWithAView is a SwiftUI package that lets you add accessory views to your context menu interactions, with UIKit's private _UIContextMenuAccessoryView.
Compatible with iOS 16 and later

Warning

This package uses a private API (_UIContextMenuAccessoryView) which may be unstable, and could change or break in future iOS releases. Use with caution and for experimentation. Anyone using this in App Store releases does so at their own risk.

Demo

Example


contextMenuAccessory

contextMenuAccessory is a SwiftUI modifier that lets you attach an accessory view to a .contextMenu. You can control the accessory's placement, location, alignment, and tracking axis. There are two variants: one for simple accessory views and another that provides a ContextMenuProxy for programmatic dismissal.

DocC documentation is available for this modifier.

Parameters

  • placement: Where the accessory is attached relative to the context menu. (Default: .center)
  • location: The location where the accessory appears. (Default: .preview)
  • alignment: How the accessory aligns within its container. (Default: .leading)
  • trackingAxis: The axis along which the accessory tracks user interaction. (Default: [.xAxis, .yAxis])
  • accessory: A view builder that returns the accessory view. Available in two variants:
    • Simple: @ViewBuilder accessory: () -> AccessoryView
    • With proxy: @ViewBuilder accessory: (ContextMenuProxy) -> AccessoryView

Examples

Basic Usage

Text("Turtle Rock")
    .padding()
    .contextMenu {
        Button(action: {}) {
            Label("Button", systemImage: "circle")
        }
    }
    .contextMenuAccessory(
        placement: .center,
        location: .preview,
        alignment: .leading,
        trackingAxis: .yAxis
    ) {
        Text("Accessory View")
            .font(.title2)
            .padding(8)
            .background(Color.blue.opacity(0.6))
            .clipShape(RoundedRectangle(cornerRadius: 12))
            .padding(16)
    }

With Programmatic Dismissal

Text("Turtle Rock")
    .padding()
    .contextMenu {
        Button(action: {}) {
            Label("Button", systemImage: "circle")
        }
    }
    .contextMenuAccessory(placement: .center) { proxy in
        VStack {
            Text("Accessory View")
                .font(.title2)

            Button("Dismiss") {
                proxy.dismiss()
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
        .background(Color.blue.opacity(0.6))
        .clipShape(RoundedRectangle(cornerRadius: 12))
    }

Acknowledgments

Special thanks to @sebjvidal for writing about _UIContextMenuAccessoryView, and helping with the development of this package!

License

This project is released under the MIT License. See LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. Before you begin, take a moment to review the Contributing Guide for details on issue reporting, coding standards, and the PR process.

Support

If you like this project, please consider giving it a ⭐️


Where to find us

Aether Seb
Twitter @AetherAurelia @SebJVidal
Threads @aetheraurelia -
Bluesky aethers.world -
LinkedIn aether -
GitHub here, obviously here!!
Website - sebvidal.com

Built with 🍏🕵️🤝👜 by Aether and Seb

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages