如何手动更改 UIMenu 中选定的 UIAction?

Gam*_*Dev 8 xcode ios swift uimenu uiaction

目标: 尝试创建一个过滤器选择屏幕(在卡片视图中),其中包含带有 UIMenu 项目的 UIButtons。当我选择任何过滤器并单击“应用过滤器”按钮时,我会关闭过滤器视图控制器并返回到集合视图屏幕以使用所选过滤器刷新数据。

问题: 在已选择过滤器的情况下,当我想再次返回以更改任何过滤器时,我单击过滤器按钮以打开过滤器视图控制器,但显然没有保留任何 UIMenu 选择,因为它们首先重置为默认值索引设置。

如何解决?: 当我的数据从filterVC传回主列表屏幕时,我传递了所选UIMenu的标题。我想我可以将其传递回filterVC并将菜单默认为传入的数据(即可以搜索标题并使其成为UIMenu中选定的UIAction),但是我似乎找不到一种方法手动选择哪个 UIAction 应该是 UIMenu 的选定状态!

    var spaceTypeMenu: UIMenu {
    return UIMenu(title: "Space Type", image: nil, identifier: nil, options: [], children: spaceTypeMenuItems)
}

    private var spaceTypeMenuItems: [UIAction] {
    return [
        UIAction(title: "All", handler: { (_) in }),
        UIAction(title: "Meeting Room", handler: { (_) in }),
        UIAction(title: "Desk", handler: { (_) in }),
        UIAction(title: "Boardroom", handler: { (_) in })
    ]
}
Run Code Online (Sandbox Code Playgroud)

然后下面是从viewdidload()中调用的

func createSpaceTypeMenu() {
    spaceTypeButton?.menu = spaceTypeMenu
    spaceTypeButton?.showsMenuAsPrimaryAction = true
}
Run Code Online (Sandbox Code Playgroud)

选择过滤器后,我将它们传回之前的 VC:

@IBAction func applyFiltersButtonPressed(_ sender: UIButton) {
    self.dismiss(animated: true) {
        let filter = Filters(site: self.siteButton?.titleLabel?.text,
                             spaceType: self.spaceTypeButton?.titleLabel?.text,
                             date: self.datePickerView.datePickerView?.date,
                             duration: self.selectedDuration)
        self.applyFiltersCallback?(filter)
    }
}
Run Code Online (Sandbox Code Playgroud)

Site、Spacetype、duration 都是带有用于过滤器选项的 UIMenu 的 UI 按钮,这些选项现在只是硬编码,如上所述。

我想要发生的是,如果我在调用 applyFiltersButtonPressed() 来关闭 VC 之前选择了“Desks”,那么当我回到此 FiltersVC 时,我希望“Desks”仍被选为 UIbutton 中的文本,并且还希望勾选“办公桌”旁边的选项,并且不希望菜单项默认返回第一个选项“全部”。

希望这是有道理的吗?

Gam*_*Dev 9

我自己找到了如何做到这一点,希望它可以帮助其他与我有同样处境的人:

private func updateActionState(actionTitle: String? = nil, menu: UIMenu) -> UIMenu {
    if let actionTitle = actionTitle {
        menu.children.forEach { action in
            guard let action = action as? UIAction else {
                return
            }
            if action.title == actionTitle {
                action.state = .on
            }
        }
    } else {
        let action = menu.children.first as? UIAction
        action?.state = .on
    }
    return menu
}
Run Code Online (Sandbox Code Playgroud)

并且可以通过以下方式调用:

private func createSiteMenu(actionTitle: String? = nil) {
    let menu = UIMenu(title: "Site", image: nil, identifier: nil, options: [], children: siteMenuItems)
    siteButton?.menu = updateActionState(actionTitle: actionTitle, menu: menu)
    siteButton?.showsMenuAsPrimaryAction = true
}
Run Code Online (Sandbox Code Playgroud)