How to Support Menu Bar Copy/Paste/Cut/Delete Commands on iPadOS with SwiftUI?
(Xcode 26 beta 4, iPadOS 26 beta 4)
We’re working on adding menu bar support to our SwiftUI app on iPadOS, aiming to provide a more consistent and productive experience across platforms.
However, we’ve encountered a challenge when trying to handle standard editing commands like Copy, Cut, Paste, and Delete from the menu bar:
On iPadOS, SwiftUI modifiers such as onCopyCommand, onCutCommand, onPasteCommand, and onDeleteCommand appear to be unavailable.
Additionally, since we can’t hide or override the default app menus, we’re unsure how to hook into or replace their behavior effectively.
Question:
What’s the recommended way to support standard editing actions like copy/paste via the menu bar in SwiftUI on iPadOS? Are there any workarounds or APIs we might have overlooked?
Any guidance or best practices would be greatly appreciated!
Feedback ID: FB18792279
Posts under iPadOS tag
174 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hi everyone,
I’m building an iOS app that originally targeted iPhone using NavigationStack. Now I’m adapting it for iPad and switched to using NavigationSplitView to support a three-column layout.
The structure looks like this:
NavigationSplitView {
A // Sidebar
} content: {
B // Middle column – this shows a list
} detail: {
C // Detail view
}
The issue is with the list shown in view B (the content column). It appears completely unstyled, as if it’s using .listStyle(.plain) — with no background material, and a very flat look.
I can understand that this might be intentional on iPad to visually distinguish the three columns.
However, the problem is that this same unstyled list also appears on iPhone, even though iPhone only shows a single column view at a time!
I tried explicitly setting .listStyle(.insetGrouped) or .listStyle(.grouped) on the list in view B, but it makes no difference.
When I go back to NavigationStack, the list in B is styled properly, just as expected — but then I lose the enhanced iPad layout.
What I’m looking for:
I’d like to keep using NavigationSplitView, but I want the list in the content column (view B) to use the default iOS list styling, at least on iPhone.
Is there any way to achieve this?
Thanks!
Hi everyone,
I’m building an iOS app that originally targeted iPhone using NavigationStack. Now I’m adapting it for iPad and switched to using NavigationSplitView to support a three-column layout.
The structure looks like this:
NavigationSplitView {
A // Sidebar
} content: {
B // Middle column – this shows a list
} detail: {
C // Detail view
}
The issue is with the list shown in view B (the content column). It appears completely unstyled, as if it’s using .listStyle(.plain) — with no background material, no grouped sections, and a very flat look.
I can understand that this might be intentional on iPad to visually distinguish the three columns.
However, the problem is that this same unstyled list also appears on iPhone, even though iPhone only shows a single column view at a time!
I tried explicitly setting .listStyle(.insetGrouped) or .listStyle(.grouped) on the list in view B, but it makes no difference.
When I go back to NavigationStack, the list in B is styled properly, just as expected — but then I lose the enhanced iPad layout.
What I’m looking for:
I’d like to keep using NavigationSplitView, but I want the list in the content column (view B) to use the default iOS list styling, at least on iPhone.
Is there any way to achieve this?
Thanks!
By default, a window on iPadOS 26 can be dragged by touching and dragging the top ~30 points of that window. If the window's root view controller is a UINavigationController with a navigation bar, the window can be dragged by touching and dragging anywhere in that navigation bar. In Apple Calendar, I can drag a window anywhere above the grid of weeks and days.
I have an app with a custom navigation controller. My navigation controller is not a subclass of UINavigationController. How can I define what portion of the window should let the user drag that window across the screen on iPad?
I’m working on an old iPad app with a concept that only works in landscape mode. The app’s content is not dynamic and can’t be rearranged depending on the window size. To ensure a good user experience, I set the UIRequiresFullScreen key to true in the Info.plist.
Despite this, it’s still possible in iPadOS 26 to resize an app that requires fullscreen. When this happens, the three-dot button overlaps the content, and elements placed in the top-left corner become hard to access.
Is there a way to detect when an app is resized and/or when the three-dot button overlaps the app?
The UIScreen / UIScene or UIWindow bounds don’t seem to change when UIRequiresFullScreen is set to true. Also, UIScene.isFullscreen always returns false.
I disable 4 or 5 Finger Gestures on Settings.app > Multi-tasking and Gestures.
But in the third-party apps, 4-5 finger touches are sometimes immediately cancelled.
Especially, 4-5 finger swipe gesture.
I filed this issue to FB19226717.
I develop Piano instrument app. 4 or 5 finger touches are required for that kind of apps. Please fix this, Apple.
I have a new M4 iPad Air and a brand new Apple Pencil Pro. It was working well until I installed iPadOS 26.0 (23A5297m) beta. Now, when using GoodNotes to write the Pencil functions for about 6-8 seconds and then disconnects for 2-3 seconds and then reconnects. You can imagine how disruptive this is. It does the same thing trying to highlight in the Kindle app, so I think it is an iOS issue.
As I write this, I am discovering that the Pencil is not wanting to stay connected at all despite showing up in the list of Bluetooth devices and connecting temporarily. I've tried forgetting and reconnecting the Pencil several times. It is charged to 100%, and I receive the alert that the iPad detects the Pencil.
Is anyone else having this issue? Do I need to assume this is being addressed?
I have a Swift Package, it's added to both the main app and the autofill extension. The main app is an iOS app that run directly on my mac from Xcode.
I use this extension to access the bundle
import Foundation
import OSLog
class CurrentBundleFinder {}
extension Foundation.Bundle {
static let myModule: Bundle = { /* The name of your local package, prepended by "LocalPackages_" */
let bundleName = "DesignSystem_DesignSystem"
let logger = Logger(subsystem: "DesignSystem", category: "Bundle")
logger.error("Searching for bundle: \(bundleName)")
let candidates = [ /* Bundle should be present here when the package is linked into an App. */
Bundle.main.resourceURL, /* Bundle should be present here when the package is linked into a framework. */
Bundle(for: CurrentBundleFinder.self).resourceURL, /* For command-line tools. */
Bundle.main.bundleURL, /* Bundle should be present here when running previews from a different package (this is the path to "…/Debug-iphonesimulator/"). */
Bundle(for: CurrentBundleFinder.self).resourceURL?.deletingLastPathComponent().deletingLastPathComponent(), /* For app extensions - look in parent app bundle */
Bundle.main.bundleURL.deletingLastPathComponent().deletingLastPathComponent(),
]
logger.error("all bundle: \(candidates, privacy: .public)")
for (index, candidate) in candidates.enumerated() {
logger.error("Checking candidate \(index): \(candidate?.absoluteString ?? "nil", privacy: .public)")
let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
logger.error("Bundle path: \(bundlePath?.absoluteString ?? "nil", privacy: .public)")
if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
logger.error("Successfully found bundle at: \(bundlePath?.absoluteString ?? "unknown", privacy: .public)")
return bundle
}
}
logger.error("Unable to find bundle named \(bundleName)")
fatalError("unable to find bundle named \(bundleName)")
}()
}
Bellow is the log from the main app and the autofill extension
log.txt
I have check that /private/var/folders/cb/fctmx0_x3_dbxy_9wnm7g0s40000gn/X/1CC84EBB-DAC0-5120-9346-5EFBC8691CF1/d/Wrapper/Proton Pass.app/PlugIns/AutoFill.appex/DesignSystem_DesignSystem.bundle
exist in the file system, but the autofill extension is unable to create a bundle from that
Hi everyone 👋
I’ve been using the Apple Pencil Pro with my iPad Pro M4 and absolutely love it — the squeeze gesture, rotation, and haptics are amazing for creative work. But I’ve run into a little roadblock…
Right now, only one Pencil Pro can be paired at a time. So while one is charging, you can’t use another as a backup without unpairing and re-pairing, which interrupts the workflow.
I’d really love to see one of two things:
The ability to use one Pencil while another charges
or
An official external charger (or support for third-party ones)
Personally, I’d happily buy both a second Pencil and a charger if this became possible. I’ve even chatted with other creatives who feel the same — it would make a huge difference for long projects or working on the go.
Just wanted to share this idea and see if anyone else here would like this too. Thanks for reading!
I am using an iPad Pro 11” on iOS 26 dev beta. I try to open 12+ apps and they don’t work. I have tried force restarting the device and checking settings and everything seems to be in order.
when using CNContactViewController to present a contact detail info, the system CNContactViewController appear some UI issues.
On iOS 26, the Poster avatar overlaps with the title "Edit device contact"
On iPadOS26 with device(not simulator), when click 'Add photo', the CNContactViewController will auto dismiss, and the console output some error log:
below are the sample code:
AppDelegate.swift:
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
let window: UIWindow = UIWindow()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let vc = SplitViewController(primary: TabBarViewController(), secondary: ViewController())
window.rootViewController = vc
window.makeKeyAndVisible()
return true
}
}
SplitViewController.swift:
import UIKit
class SplitViewController: UISplitViewController {
init(primary: UIViewController, secondary: UIViewController) {
super.init(nibName: nil, bundle: nil)
preferredDisplayMode = .oneBesideSecondary
presentsWithGesture = false
delegate = self
viewControllers = [primary, secondary]
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension SplitViewController: UISplitViewControllerDelegate {
}
TabBarViewController.swift:
import UIKit
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
class HomeViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
navigationItem.title = "Home"
tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 0)
}
}
class TabBarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let homeVC = HomeViewController()
let homeNav = UINavigationController(rootViewController: homeVC)
viewControllers = [homeNav]
ContactManager.shared.getAllContactIdentifiers()
}
}
ViewController.swift:
import UIKit
import Contacts
import ContactsUI
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemPink
let button = UIButton(frame: .zero)
button.backgroundColor = .orange
button.setTitle("show contact", for: .normal)
button.addTarget(self, action: #selector(showContactInfo), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
button.widthAnchor.constraint(equalToConstant: 200).isActive = true
button.heightAnchor.constraint(equalToConstant: 60).isActive = true
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
@objc private func showContactInfo() {
print("showContactInfo")
let identifier = ContactManager.shared.identifiers[0]
let currentContact = try? CNContactStore().unifiedContact(withIdentifier: identifier, keysToFetch: [CNContactViewController.descriptorForRequiredKeys()])
guard let contact: CNMutableContact = currentContact?.mutableCopy() as? CNMutableContact else {
return
}
let vc = CNContactViewController(forNewContact: contact)
vc.delegate = self
vc.title = "Edit Device Contact"
vc.allowsActions = false
vc.contactStore = CNContactStore()
let navigationVC: UINavigationController = UINavigationController(rootViewController: vc)
let appDelegate = UIApplication.shared.delegate as? AppDelegate
appDelegate?.window.rootViewController?.present(navigationVC, animated: true, completion: nil)
}
}
extension ViewController: CNContactViewControllerDelegate {
public func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
viewController.dismiss(animated: true, completion: nil)
}
}
Hello, I have been trying for some time to change the color of native UITabBar in UITabBarController through UITabBarAppearance, but nothing works and the text is still black in the Xcode Beta 3 on iPadOS 26 while it works correctly in the previous OS versions.
Here is the code:
let color = UIColor.white
let stackedAppearance = UITabBarItemAppearance()
stackedAppearance.normal.iconColor = color
stackedAppearance.normal.titleTextAttributes = [
.foregroundColor: color
]
stackedAppearance.selected.iconColor = color
stackedAppearance.selected.titleTextAttributes = [
.foregroundColor: color
]
let inlineAppearance = UITabBarItemAppearance()
inlineAppearance.normal.iconColor = color
inlineAppearance.normal.titleTextAttributes = [
.foregroundColor: color
]
inlineAppearance.selected.iconColor = color
inlineAppearance.selected.titleTextAttributes = [
.foregroundColor: color
]
let tabAppearance = UITabBarAppearance()
tabAppearance.compactInlineLayoutAppearance = inlineAppearance
tabAppearance.inlineLayoutAppearance = inlineAppearance
tabAppearance.stackedLayoutAppearance = stackedAppearance
UITabBar.appearance().standardAppearance = tabAppearance
UITabBar.appearance().scrollEdgeAppearance = tabAppearance
I work on a universal app that targets both iPhone and iPad. Our iPad app currently requires full screen. When testing on the latest iPadOS 26 beta, we see the following warning printed to the console:
Update the Info.plist: 1) `UIRequiresFullScreen` will soon be ignored. 2) Support for all orientations will soon be required.
It will take a fair amount of effort to update our app to properly support presentation in a resizable window. We wanted to gauge how urgent this change is. Our testing has shown that iPadOS 26 supports our app in a non-resizable window.
Can someone from Apple provide any guidance as to how soon “soon” is? Will UIRequiresFullScreen be ignored in iPadOS 26? Will support for all orientations be required in iPadOS 26?
To adopt glass effect in custom view, we are using glassEffect modifier. It is working fine iOS26. However in iPadOS 26 beta 3, app is getting crash as soon as app launch. In iPad simulator it's working fine.
Symbol not found: _$s7SwiftUI4ViewPAAE11glassEffect_2inQrAA5GlassV_qd__tAA5ShapeRd__lF
Our app includes the UIRequiresFullScreen plist key, but the iPadOS 26 betas seem to ignore this. The window handle is still displayed, and while the window aspect ratio seems to be constrained, you can still adjust it and arrange it alongside other apps. We do not want to support windowing or multi-tasking, and the WWDC sessions indicated there would be a way to opt out of the new windowing system. Has UIRequiresFullScreen been silently deprecated, or are we missing something in our implementation?
With the new multi-windowing design in iPadOS 26, the behavior of openWindow() has changed.
In iPadOS 18, if I called openWindow(), I would go from a full-screen window to two side-by-side windows. That allowed my app to meet the goal of the user; keep some information on the screen while being able to navigate through the app in the other window.
In iPadOS 26 (beta 3), this no longer works. Instead, a new Window opens ON top of the current window. I am looking for some mechanism to help the user see that two windows are now present and then easily move them on the screen (tiled, side-by-side) or whatever else they would prefer.
I am using XCODE-BETA (Version 26.0 beta (17A5241e)) on a Mac (running Sequoia 15.5) to develop an app using FoundationModel. I am testing on an iPad (iPad Pro 11 in, 2nd Gen, running iPadOS 26 Beta 3).
My app works fine when I run it in the simulator (iPad 26.0).
So I upgraded my iPad Pro to iPadOS 26 beta 3 to try it on a real device.
When I run it on the device, I get an error about symbols not found. [See details below]
Any idea what I need to change in my development configuration to allow me to run/test my app on a real device running iPadOS 26 beta 3?
Thanks in advance,
Charlie
dyld[1132]: Symbol not found: _$s6WebKit0A4PageC4loadyAC12NavigationIDVSg10Foundation10URLRequestVF
Referenced from: <65E40738-6E3A-3F65-B39F-9FD9A695763C> /private/var/containers/Bundle/Application/34F9D5CE-3E54-4312-8574-10B506C713FA/Blossom.app/Blossom.debug.dylib
Expected in: /System/Library/Frameworks/WebKit.framework/WebKit
Symbol not found: _$s6WebKit0A4PageC4loadyAC12NavigationIDVSg10Foundation10URLRequestVF
Referenced from: <65E40738-6E3A-3F65-B39F-9FD9A695763C> /private/var/containers/Bundle/Application/34F9D5CE-3E54-4312-8574-10B506C713FA/Blossom.app/Blossom.debug.dylib
Expected in: /System/Library/Frameworks/WebKit.framework/WebKit
dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libLogRedirect.dylib:/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/usr/lib/libViewDebuggerSupport.dylib
Symbol not found: _$s6WebKit0A4PageC4loadyAC12NavigationIDVSg10Foundation10URLRequestVF
Referenced from: <65E40738-6E3A-3F65-B39F-9FD9A695763C> /private/var/containers/Bundle/Application/34F9D5CE-3E54-4312-8574-10B506C713FA/Blossom.app/Blossom.debug.dylib
Expected in: /System/Library/Frameworks/WebKit.framework/WebKit
dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libLogRedirect.dylib:/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/usr/lib/libViewDebuggerSupport.dylib
I’ll preface this by saying I’ve submitted a DTS ticket with essentially this exact text, but I thought I’d also post about it here to get some additional input. Apple engineers: the case ID is 14698374, for your reference.
I have an observable class, called NavigationModel, that powers navigation in my SwiftUI app. It has one important property, navigationSelection, that stores the currently selected view. This property is passed to a List in the sidebar column of a NavigationSplitView with two columns. The list has NavigationLinks that accept that selection as a value parameter. When a NavigationLink is tapped, the detail column shows the appropriate detail view per the navigationSelection property’s current value via a switch statement. (This navigationSelection stores an enum value.)
This setup allows for complete programmatic navigation as that selection is effectively global. From anywhere in the app — any button, command, or app intent — the selection can be modified since the NavigationModel class uses the @Observable Swift macro. In the app’s root file, an instance of the NavigationModel is created, added as an app intent dependency, and assigned (might be the wrong verb here, but you get it) to ContentView, which houses the NavigationSplitView code.
The problem lies when more than one window is opened. Because this is all just one instance of NavigationModel — initialized in the app’s root file — the navigation selection is shared across windows. That is, there is no way for one window to show a view and another to show another view — they’re bound to the same instance of NavigationModel. Again, this was done so that app intents and menu bar commands can modify the navigation selection, but this causes unintended behavior.
I checked Apple’s sample projects, namely the “Accelerating app interactions with App Intents” (https://developer.apple.com/documentation/appintents/acceleratingappinteractionswithappintents) and “Adopting App Intents to support system experiences” (https://developer.apple.com/documentation/appintents/adopting-app-intents-to-support-system-experiences) projects, to see how Apple recommends handling this case. Both of these projects have intents to display a view by modifying the navigation selection. They also have the same unintended behavior I’m experiencing in my app. If two windows are open, they share the navigation selection.
I feel pretty stupid asking for help with this, but I’ve tried a lot to get it to work the way I want it to. My first instinct was to create a new instance of NavigationModel for each window, and that’s about 90% of the way there, but app intents fail when there are no open windows because there are no instances of NavigationModel to modify. I also tried playing with FocusedValue and SceneStorage, but those solutions also didn’t play well with app intents and added too much convoluted code for what should be a simple issue.
In total, what I want is:
A window/scene-specific navigation selection property that works across TabViews and NavigationSplitViews
A way to reliably modify that property’s value across the app for the currently focused window
A way to set a value as a default, so when the app launches with a window, it automatically selects a value in the detail column
The navigation selection to reset across app and window launches, restoring the default selection
Does anyone know how to do this? I’ve scoured the internet, but again, no dice. Usually Apple’s sample projects are great with this sort of thing, but all of their projects that have scene-specific navigation selection with NavigationSplitView don’t have app intents. 🤷♂️
If anyone needs additional code samples, I’d be happy to provide them, but it’s basically a close copy of Apple’s own sample code found in those two links.
I Got The Developer Beta For iOS AND iPadOS 26. On my main devices because im poor and cant buy another one.
so.. should i be worried of it being unstable? Also i didnt backup because iCloud Is Full and im not paying for a better subscription thats more expensiv.
Hi everyone!
I've considered this — what if Apple added a native system-wide feature in all of iOS, iPadOS, and macOS called “CrossRun” where you can natively execute non-App Store software like Windows or Linux apps natively on your device? But not in a sluggish emulator—this would use intelligent Apple-signed Just-In-Time (JIT) compilation inside the virtual containers, and the experience would actually perform fast and feel natural.
This is my vision for CrossRun:
Every developer, student, creative professional, and enterprise user who relies on specialized software—whether it’s legacy Windows tools, Linux-only applications, or vintage DOS and Classic Mac utilities—feels the pain of platform lock‑in. Artists can’t run niche Linux‑based graphics programs on their iPads. Engineers can’t test x64‑only binaries on Apple Silicon without juggling emulators. Retro‑gaming fans miss their favorite DOS titles. Even enterprises struggle to standardize on Apple hardware because critical Windows‑only applications won’t run seamlessly.
If we don’t push for CrossRun now, the Apple ecosystem remains siloed: iPads and iPhones will continue limited to App Store apps, Macs will still need multiple third‑party VM tools, and countless workflows stay fragmented across devices. That means slower development cycles, extra licensing costs for virtualization software, and lost opportunities for education, creativity, and business efficiency. Without CrossRun’s universal runtime, we’ll still be rebooting into different environments or paying for separate virtualization apps—year after year.
Apple already provides the building blocks: Rosetta 2, Virtualization.framework, Apple Silicon—and QEMU thrives as open‑source, battle‑tested code. With the next wave of Apple Silicon devices on the horizon, demand for cross‑architecture support, legacy‑app compatibility, and enterprise containerization is only growing. Delaying another year will cost developers, businesses, and users real time and money. Let’s show Apple that the community is ready for a truly universal, system‑integrated solution—right now.
Key features we should demand in CrossRun:
Built‑in Apple‑signed QEMU for all ISAs (x86, ARM, RISC‑V, PowerPC, 68k, MIPS, etc.)
Rosetta 2 JIT for seamless macOS and Windows x64 support
Metal‑backed 3D GPU passthrough and Vulkan→Metal / Direct3D→Metal translation
Downloadable OS and app containers via the App Store or verified repositories (Ubuntu, Windows ARM/x64, Android, Haiku, ReactOS, FreeBSD, retro OSes)
Predictive ML pre‑warm cache to speed cold starts
Dynamic resource scaling (CPU, GPU, RAM) per container
iCloud‑synced snapshots and shareable VM links for cross‑device continuity
Customizable on‑screen controls (D‑pad, virtual buttons, trackpad, keyboard) on iPhone, iPad, and macOS
Secure sandboxing via Virtualization.framework with VM disk encryption and MDM policy enforcement
Virtual LAN and VPN passthrough for container networking
Developer tooling (crossrunctl CLI, Xcode debugger integration, CI/CD support)
Plugin ecosystem and container SDK for community‑published templates and translation layers
Let Apple know it’s time to bake CrossRun into the system and unlock a universal runtime for every app, past and future, across iOS, iPadOS, and macOS.