如何修改附加到导航栏按钮的 UIMenu 的 UIAction?

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

我正在开发一个带有自定义文件浏览器的应用程序,目前我正在致力于实现复制/粘贴。我在导航栏中有一个按钮,我在该按钮上附加了

UIMenu
,以显示添加文件(包括粘贴)的选项。我希望当文件位于剪贴板中时自动启用粘贴按钮,并在剪贴板为空时自动禁用粘贴按钮。我一开始尝试这样做:

// in class definition
var pasteAction: UIAction?
@IBOutlet var addButton: UIBarButtonItem!
// in viewDidLoad()
pasteAction = UIAction(
    title: "Paste Files",
    image: UIImage(systemName: "doc.on.clipboard"),
    attributes: clipboard.isEmpty ? .disabled : [],
    handler: pasteFiles
)
addButton.menu = UIMenu(
    title: "", image: nil, identifier: nil, options: .displayInline,
    children: [folder, file, imp, pasteAction!]
)
// in copy()
pasteAction!.attributes = clipboard.isEmpty ? .disabled : []

但是,粘贴按钮仍然处于禁用状态。 (离开并重新进入视图控制器时,粘贴按钮 is 已启用。)我还尝试用具有相同子项的新菜单替换菜单:

pasteAction!.attributes = clipboard.isEmpty ? .disabled : []
var c = Array(addButton.menu!.children[0...2])
c.append(pasteAction!)
addButton.menu = addButton.menu!.replacingChildren(c)

这也不起作用。最后,我尝试创建一个新的

UIAction
,以防万一实际上无法修改它:

var c = Array(addButton.menu!.children[0...2])
c.append(UIAction(
    title: "Paste Files",
    image: UIImage(systemName: "doc.on.clipboard"),
    attributes: FilesViewController.clipboard.isEmpty ? .disabled : [],
    handler: pasteFiles
))
addButton.menu = addButton.menu!.replacingChildren(c)

但这仍然没有任何作用。我是否缺少一些需要调用的更新函数?或者加载视图后我无法修改导航栏按钮的菜单吗?

ios swift uikit uibarbuttonitem uimenu
1个回答
0
投票

我知道在 UIButton 菜单中切换禁用/启用的唯一方法:

问题有点像更改所选索引。

看来您必须实际复制、更改,然后更改子列表中的该项目。

这是我们解决这两个问题的代码,它似乎有效:

“选择外观”一...

///Utils for the "popup" type of UIButton
extension UIButton {
    
    ///For the "popup" type buttons, set the selected item.
    ///If the button is the wrong type or it is otherwise not possible, nothing is done.
    func forceSelectedIndex(_ index: Int) {
            guard (self.menu != nil) else {
                return print("forceSelectedIndex impossible")
            }
            guard index >= 0 && index < self.menu!.children.count else {
                return print("forceSelectedIndex impossible")
            }
            (self.menu!.children[index] as? UIAction)?.state = .on
    }
    

以及禁用问题...

    ///Note that finding the correct index may itself be tricky.
    ///For the "popup" type buttons, for one menu item, set that item disabled (or anti-disabled).
    ///If the button is the wrong type or it is otherwise not possible, nothing is done.
    func force(disabled: Bool, onMenuActionIndex ix: Int) {
        guard (self.menu != nil) else {
            return print("forceDisabled impossible")
        }
        guard ix >= 0 && ix < self.menu!.children.count else {
            return print("forceDisabled impossible")
        }
        
        guard let _ = self.menu!.children[ix] as? UIAction else {
            return print("forceDisabled impossible")
        }
        
        var atts: UIMenuElement.Attributes = (self.menu!.children[ix] as! UIAction).attributes
        if disabled {
            atts.insert(.disabled)
        }
        else {
            atts.remove(.disabled)
        }
        (self.menu!.children[ix] as! UIAction).attributes = atts
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.