【问题标题】:How to manually change the selected UIAction inside UIMenu?如何手动更改 UIMenu 中选定的 UIAction?
【发布时间】:2021-12-17 06:54:04
【问题描述】:

目标: 尝试创建一个过滤器选择屏幕(在卡片视图中),其中包含带有 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 })
    ]
}

那么下面是从viewdidload()中调用的

func createSpaceTypeMenu() {
    spaceTypeButton?.menu = spaceTypeMenu
    spaceTypeButton?.showsMenuAsPrimaryAction = true
}

选择过滤器后,我将它们传递回之前的 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)
    }
}

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

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

希望这有意义吗?

【问题讨论】:

    标签: ios swift xcode uimenu uiaction


    【解决方案1】:

    谢谢,这可以解决我的类似问题。我正在使用 ios15 弹出和下拉菜单,但希望从枚举中填充菜单,其中原始值作为菜单选项。

    enum SortOrder: String, Codable, CaseIterable {
        case name = "Name"
        case category = "Category"
        case qty = "Quantity"
        case value = "Value"
        case token = "Token"
    }
    let sortClosure = { [self] (action: UIAction) in  
        // closure actions based on self.sortOrderPopup.currentTitle!
    }
    
    var sortOrderPopupOptions: [UIAction] = []
    for sortOption in ListLibrary.SortOrder.allCases {
        sortOrderPopupOptions.append(UIAction(title: sortOption.rawValue, handler: sortClosure))
    }
    
    sortOrderPopup.menu = UIMenu(children: sortOrderPopupOptions)
    menuSelection = currentList.sortOrder.rawValue
    
    sortOrderPopup.menu = updateActionState(actionTitle: menuSelection, menu: sortOrderPopup.menu!)
    

    您的解决方案完美运行,可以调整以修改菜单的其他属性!

    【讨论】:

      【解决方案2】:

      自己找到了如何做到这一点,希望它可以帮助和我一样的人:

      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
      }
      

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

      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
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-18
        • 2021-08-20
        • 2020-11-08
        • 1970-01-01
        • 1970-01-01
        • 2018-02-04
        • 1970-01-01
        相关资源
        最近更新 更多