我正在开发一个带有自定义文件浏览器的应用程序,目前我正在致力于实现复制/粘贴。我在导航栏中有一个按钮,我在该按钮上附加了
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)
但这仍然没有任何作用。我是否缺少一些需要调用的更新函数?或者加载视图后我无法修改导航栏按钮的菜单吗?
问题有点像更改所选索引。
看来您必须实际复制、更改,然后更改子列表中的该项目。
这是我们解决这两个问题的代码,它似乎有效:
“选择外观”一...
///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
}
}