Search code examples
swiftcontextmenuios13

ContextMenuConfigurationForRowAt in iOS13


In this video in WWDC19 seasons, Modernizing Your UI for iOS 13, this method is to create a context menu, but I get an error when using it:

@available(iOS 13.0, *)
func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
    let actionProvider = (suggestedActions: [UIMenuElement])-> UIMenu? // in this line i got an error {
        let editMenu = UIMenu(title: "Edit...", children: [
        UIAction(title: "Copy") {},
        UIAction(title: "Duplicate") {}
        ])
        return UIMenu(children: [
        UIAction(title: "Share") {},
        editMenu,
        UIAction(title: "Delete", style: .destructive) {}
        ])
    }

    return UIContextMenuConfiguration(identifier: "unique-ID" as NSCopying,
                                      previewProvider: nil,
                                      actionProvider: actionProvider)
}

The error appears in the line -> UIMenu? and says Expected type after '->'. Could anyone help me how to solve it?


Solution

  • You have many syntax errors:

    func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
        let actionProvider: UIContextMenuActionProvider = { _ in
            let editMenu = UIMenu(title: "Edit...", children: [
                UIAction(title: "Copy") { _ in },
                UIAction(title: "Duplicate") { _ in }
            ])
            return UIMenu(title: "Title", children: [
                UIAction(title: "Share") { _ in },
                editMenu
            ])
        }
    
        return UIContextMenuConfiguration(identifier: "unique-ID" as NSCopying, previewProvider: nil, actionProvider: actionProvider)
    }
    

    Note that some of the API's changed after WWDC and you should consider updating them similar to above code. You can check a comprehensive Guide to iOS Context Menus wrote by Kyle Bashour.

    Example:

    func makeContextMenu() -> UIMenu {
        let rename = UIAction(title: "Rename Pupper", image: UIImage(systemName: "square.and.pencil")) { action in
            // Show rename UI
        }
    
        // Here we specify the "destructive" attribute to show that it’s destructive in nature
        let delete = UIAction(title: "Delete Photo", image: UIImage(systemName: "trash"), attributes: .destructive) { action in
            // Delete this photo 😢
        }
    
        // The "title" will show up as an action for opening this menu
        let edit = UIMenu(title: "Edit...", children: [rename, delete])
    
        let share = UIAction(...)
    
        // Create our menu with both the edit menu and the share action
        return UIMenu(title: "Main Menu", children: [edit, share])
    }
    
    func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
        return UIContextMenuConfiguration(identifier: nil, previewProvider: nil, actionProvider: { suggestedActions in
    
            // "puppers" is the array backing the collection view
            return self.makeContextMenu(for: self.puppers[indexPath.row])
        })
    }