简体   繁体   中英

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.

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

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.

It works for me:

if let keyWindow = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.flatMap { $0.windows }.first { $0.isKeyWindow } {
    keyWindow.overrideUserInterfaceStyle = darkThemeIsNeeded ? .dark : .light
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM