ShortcutItem
Before the iPhone 11, there was a home-screen interaction called 3D Touch, which has now been changed to Haptic Touch. It is a three-dimensional touch technology that can sense different touch pressures. By using this technology, you can set up up to 4 different ShortcutItem (shortcut menu) for App, which can be implemented in static and dynamic two ways.
- Static configuration through the info.plist file.
<key>UIApplicationShortcutItems</key>
<array>
<dict>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeSearch</string>
<key>UIApplicationShortcutItemSubtitle</key>
<string>subtitle</string>
<key>UIApplicationShortcutItemTitle</key>
<string>The title</string>
<key>UIApplicationShortcutItemType</key>
<string>search</string>
</dict>.</array>
Copy the code
- Dynamic configuration is set by code.
extension AppDelegate {
func shortcutItems(a) {
/ / icon
let icon1 = UIApplicationShortcutIcon(systemImageName: "qrcode.viewfinder") // System image
let icon2 = UIApplicationShortcutIcon(templateImageName: "settings") // Create a custom image
let icon3 = UIApplicationShortcutIcon(type: .search) // System type
/ / the menu
let item1 = UIApplicationShortcutItem(type: "1", localizedTitle: "Scan", localizedSubtitle: nil, icon: icon1, userInfo: nil)
let item2 = UIApplicationShortcutItem(type: "2", localizedTitle: "Settings", localizedSubtitle: nil, icon: icon2, userInfo: nil)
let item3 = UIApplicationShortcutItem(type: "3", localizedTitle: "Search", localizedSubtitle: nil, icon: icon3, userInfo: nil)
/ / set
UIApplication.shared.shortcutItems = [item1, item2, item3]
}
}
Copy the code
- Click event Response.
Before iOS13, use the AppDelegate delegate delegate method
func application(_ application: UIApplication.performActionFor shortcutItem: UIApplicationShortcutItem.completionHandler: @escaping (Bool) - >Void) {
if shortcutItem.type = = "1" {
window?.rootViewController?.view.backgroundColor = .red
} else if shortcutItem.type = = "2" {
window?.rootViewController?.view.backgroundColor = .green
} else if shortcutItem.type = = "3" {
window?.rootViewController?.view.backgroundColor = .blue
}
}
// After iOS13, the AppDelegate delegate delegate method will not be called, you need to use the SceneDelegate delegate method
func windowScene(_ windowScene: UIWindowScene.performActionFor shortcutItem: UIApplicationShortcutItem.completionHandler: @escaping (Bool) - >Void) {
if shortcutItem.type = = "1" {
window?.rootViewController?.view.backgroundColor = .red
} else if shortcutItem.type = = "2" {
window?.rootViewController?.view.backgroundColor = .green
} else if shortcutItem.type = = "3" {
window?.rootViewController?.view.backgroundColor = .blue
}
}
Copy the code
UIMenu
- UIMenu was introduced in iOS 13 to make it easy to create program menus and context menus.
import UIKit
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Displays the toolbar
navigationController?.isToolbarHidden = false
// The menu is bound to UIBarButtonItem (constructor for iOS 14)
let addNewItem = UIBarButtonItem(systemItem: .add, primaryAction: nil, menu: createMenu())
// Put it in the toolbar
toolbarItems = [addNewItem]
}
func createMenu(a) -> UIMenu {
// The first menu
let favorite = UIAction(title: "Favorite", image: UIImage(systemName: "heart.fill")) { _ in
print("favorite")}// The second menu
let share = UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up.fill")) { _ in
print("share")}// The third menu
let delete = UIAction(title: "Delete", image: UIImage(systemName: "trash.fill"), attributes: [.destructive]) { _ in
print("delete")}// Create a menu group
let menuActions = [favorite, share, delete]
/ / create UIMenu
let addNewMenu = UIMenu(children: menuActions)
return addNewMenu
}
}
Copy the code
- Introduced in iOS 14
UIDeferredMenuElement
Allows you to create UIMenu asynchronously and dynamically configure the contents of the menu.
import UIKit
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Put it in the navigation bar
navigationItem.rightBarButtonItem = UIBarButtonItem(systemItem: .add, primaryAction: nil, menu: createMenu())
}
func createMenu(a) -> UIMenu {
// Load the Bundle directly from the Bundle
let menuItemsForUser = Bundle.main.decode([RemoteItem].self, from: "menu.json")
/ / create UIDeferredMenuElement
let dynamicElements = UIDeferredMenuElement { completion in
/ / create the UIAction
let actions = menuItemsForUser.map { item in
UIAction(title: item.title, image: UIImage(systemName: item.icon)) { _ in
print("\(item.title) tapped")}}// Be sure to invoke the completion processing
completion(actions)
}
return UIMenu(children: [dynamicElements])
}
}
/ / the menu Model
struct RemoteItem: Codable {
let title: String
let icon: String
}
// Load the file and go to Model
extension Bundle {
func decode<T: Decodable> (_ type: T.Type.from file: String) -> T {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Failed to find \(file) in bundle.")}guard let data = try? Data(contentsOf: url) else {
fatalError("Failed to load \(file) from bundle.")}guard let model = try? JSONDecoder().decode(T.self, from: data) else {
fatalError("Failed to decode \(file) from bundle.")}return model
}
}
Copy the code
The JSON content is as follows:
[{"title": "Favorite"."icon": "heart.fill"
},
{
"title": "Share"."icon": "square.and.arrow.up.fill"
},
{
"title": "Delete"."icon": "trash.fill"}]Copy the code
Context Menus
- WWDC 2019 introduced Context Menus, which are also triggered by pressing. Unlike Haptic Touch, Context Menus are used to set Menus in the App.
- If you want to enable a context menu, you need to create one
UIContextMenuInteraction
Add it to a triggered UIView, specify a delegate, create the UIMenu in the delegate method and return itUIContextMenuConfiguration
Can.
import UIKit
class ViewController: UIViewController {
// Need to turn on User Interaction
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad(a) {
super.viewDidLoad()
/ / create UIContextMenuInteraction
let interaction = UIContextMenuInteraction(delegate: self)
/ / add UIContextMenuInteraction
// Use any other UIView
imageView.addInteraction(interaction)
}
}
// Proxy method
extension ViewController: UIContextMenuInteractionDelegate {
func contextMenuInteraction(_ interaction: UIContextMenuInteraction.configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
// The first menu
let favorite = UIAction(title: "Favorite", image: UIImage(systemName: "heart.fill")) { action in
print("favorite")}// The second menu
let share = UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up.fill")) { action in
print("share")}// The third menu
let delete = UIAction(title: "Delete", image: UIImage(systemName: "trash.fill"), attributes: [.destructive]) { action in
print("delete")}/ / return UIContextMenuConfiguration
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in
UIMenu(children: [favorite, share, delete])
}
}
}
Copy the code