如何在单击表格视图行时以编程方式呈现菜单,就像在 iOS 16 日历应用程序中一样?

问题描述 投票:0回答:4

在iOS 16日历应用中,“重复”等选项有了新的下拉菜单样式,当点击该行的任何位置时,都会出现一个菜单。表格视图单元格的右侧有一个 V 形向上和 V 形向下图标。

如何在 iOS 16 中执行此操作?上下文菜单是通过长按触发的,但这种新样式是通过单击触发的。

ios uitableview uimenu uiaction
4个回答
1
投票

这似乎仅限于 SwiftUI。我在 iOS 16 UIKit 中找不到实现此目的的更改。在 SwiftUI 中:

import SwiftUI

struct SettingsView: View {
    @State private var selectedFlavor: Flavor = .chocolate

    var body: some View {
        List {
            Picker("Flavor", selection: $selectedFlavor) {
                Text("Chocolate").tag(Flavor.chocolate)
                Text("Vanilla").tag(Flavor.vanilla)
                Text("Strawberry").tag(Flavor.strawberry)
            }
        }
    }
}

struct SettingsView_Previews: PreviewProvider {
    static var previews: some View {
        SettingsView()
    }
}

enum Flavor: String, CaseIterable, Identifiable {
    case chocolate, vanilla, strawberry
    var id: Self { self }
}

1
投票

您可以将 UIButton 添加到 TableViewCell 并填充整个空间。利用UIButton的menu属性实现系统日历效果

button.menu = menu

你可以查看我写的代码,希望对你有帮助。 https://github.com/zhi6w/TableViewCellWithMenuButton


0
投票

从 iOS 16 开始,你可以做到这一点,尽管使用水平布局的编辑菜单,或者使用长按手势,这两种用户都可能预料不到。

在第一种情况下,您将 UIMenu 提供给编辑菜单委托方法,而在后一种情况下,您使用上下文菜单的委托菜单。对于水平菜单,菜单名称越短越好,特别是当您有超过 2 或 3 个项目时,这样用户就不必单击末尾的直角三角形来显示更多项目。

委托方法分别返回一个 UIMenu,您可以在委托方法中直接创建它,或者您可以将其设置为重用触发的提及,也许在 tableView 单元格内使用弹出 UIButton() ,这样您就可以得到更好的覆盖范围,以防用户不点击按钮本身。


方法1:自定义“编辑”菜单(例如当前水平菜单):
var editMenuInteraction : UIEditMenuInteraction! = nil

override func viewDidLoad() {
    editMenuInteraction = UIEditMenuInteraction(delegate: self)
}

extension MyViewController: UIEditMenuInteractionDelegate {
    
    func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? {


        let myAction = UIAction(title: "Action1", image: UIImage(systemName: "bell"), identifier: nil) { action in
            print("MyAction tapped")
        }

        let anotherAction = UIAction(title: "Action2", image: UIImage(systemName: "person"), identifier: nil) { action in
            print("AnotherAction tapped")
        }

        .
        .
        .

        return UIMenu(title: "", children: [myAction, anotherAction])
    }
}

extension MyViewController : UITableViewDelegate {
   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            cell.addInteraction(editMenuInteraction)
   }

   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let interaction = editMenuInteraction {
           let rect = tableView.rectForRow(at: indexPath)
           let absoluteRect = tableView.convert(rect, to: tableView.superview)
           let configuration = UIEditMenuConfiguration(identifier: nil, sourcePoint: absoluteRect.origin)
           interaction.presentEditMenu(with: configuration)
        }
    }
}

方法 2:上下文菜单(例如在单元格上长按手势)
// In your cellForRowAt tableView delegate method:

let interaction = UIContextMenuInteraction(delegate: self)
cell?.addInteraction(interaction)


extension MyViewController: UIContextMenuInteractionDelegate {
    func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
        return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
        
            let myAction = UIAction(title: "MyAction", image: UIImage(systemName: "bell"), identifier: nil) { action in
                print("MyAction tapped")
            }

            let anotherAction = UIAction(title: "AnotherAction", image: UIImage(systemName: "person"), identifier: nil) { action in
                print("AnotherAction tapped")
            }
         
            .
            .
            .

            return UIMenu(title: "", children: [myAction, anotherAction])
        }
    }
}

0
投票

可以在tableViewCell的contentView中添加UIButton显示菜单。

class TestCell: UITableViewCell {
  lazy var menuButton: UIButton = {
    let button = UIButton()
    button.showsMenuAsPrimaryAction = true
    // custom your menu
    button.menu = UIMenu(title: "menus", children: [])
    return button
  }()

  override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: .default, reuseIdentifier: reuseIdentifier)
    contentView.addSubview(menuButton)
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.