Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to override the (dark/light) user interface style of iOS 13 Context Menus?

My app supports iOS 13 dark mode, and provides the user the option of matching the system appearance or forcing the app to always use either dark mode or light mode, irrespective of the system setting.

The app also allows presenting a Context Menu when the user presses a UILabel. However, when presenting Context Menus using UIContextMenuInteractionDelegate methods, I cannot find any way to override the dark/light appearance of the menus, nor the appearance of the UITargetedPreview view that animates when the Context Menus appear and disappear.

For example, if the iOS appearance is set to light mode and the user selects the option to force dark mode in the app, the Context Menus appear light. I would like to override that behavior so they appear dark - is there any way to achieve this? There seems to be no overrideUserInterfaceStyle property associated with Context Menus that I can find.

The code that I use is below for reference.

// Setup code

if #available(iOS 13.0, *) {
    self.textLabel.addInteraction(UIContextMenuInteraction(delegate: self))
}

// UIContextMenuInteractionDelegate

@available(iOS 13.0, *)
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
    let text = self.text
    return UIContextMenuConfiguration(identifier: nil, previewProvider: { return TextViewController(text: text) }) { [weak self] _ in
        return self?.contextMenu(for: text)
    }
}

@available(iOS 13.0, *)
private func contextMenu(for text: String) -> UIMenu {
    let copy = UIAction(title: "Copy", image: UIImage(systemName: "doc.on.doc")) { _ in
        // Perform 'text' copy
    }

    let share = UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up")) { _ in
        // Present system share sheet
    }

    return UIMenu(title: "", children: [copy, share])
}

I force the appearance of the view controller from which the Context Menu is presented using:

overrideUserInterfaceStyle = .dark // or .light

So, the problem I'm facing is not with the UI elements in my UIViewController, just the Context Menus that are presented from it.

like image 480
David Steppenbeck Avatar asked Nov 18 '19 17:11

David Steppenbeck


People also ask

How do I force light in iOS?

iOS Simulator can toggle between light and dark mode with ⌘ - command + ⇧ - shift + a shortcut. Views from both view controllers change simultaneously. Now, let try setting the overrideUserInterfaceStyle property on the view and view controller to see the difference.

Do apps have to support dark mode?

Not all apps offer an official dark mode, but many have jumped on the bandwagon in recent years. If you have at least iOS 13 or Android 10, your device will support a system-wide dark mode.

How do I opt out of dark mode Swiftui?

Opt Out of Dark Mode Entirely If you need extra time to work on your app's Dark Mode support, you can temporarily opt out by including the UIUserInterfaceStyle key (with a value of Light ) in your app's Info.

What is context menu in iOS?

In iOS and iPadOS, a context menu can display a preview of the current content near the list of commands. People can choose a command in the menu or — in some cases — they can tap the preview to open it or drag it to another area. Prefer a graphical preview that clarifies the target of a context menu's commands.


2 Answers

Override Light or Dark mode For the entire app or scene:

Add the following line to AppDelegate or SceneDelegate in iOS 13 and above.

self.window?.overrideUserInterfaceStyle = .light / .dark

Override Light or Dark mode For a specific UIViewController:

Add the following like to ViewDidLoad:

self.overrideUserInterfaceStyle = .light / .dark

Override Light or Dark mode For a specific UIView:

view.overrideUserInterfaceStyle = .light / .dark
like image 182
shbedev Avatar answered Oct 26 '22 23:10

shbedev


In 2022, I was not able to override style for UIMenu populated on long-press on collection view cell via delegate method func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration?

Context of my app:

  1. On the iOS level Appearance to Automatic
  2. Force needed UINavigationControllers / ViewControllers to .light via .overrideUserInterfaceStyle = .light (sometimes set on the navigationBar as well)

Tried to set everything related to collection's subviews or other views, simply everything which has .overrideUserInterfaceStyle property, and nothing. Long-press on collection view shows dark UIMenu if user has iOS in Dark mode. Shows light UIMenu if user has Light mode.

like image 38
peetadelic Avatar answered Oct 26 '22 23:10

peetadelic