我正在尝试以编程方式触发在按下按钮时在 WWDC24 会议“UIKit 中的新增功能”中引入的新格式面板的外观。
到目前为止,我已经通过设置
allowsEditingTextAttributes = true
启用了文本格式。这适用于通过编辑菜单显示格式面板(长按或选择文本时)。但是,我找不到一种方法可以通过按键盘工具栏中的按钮直接显示面板。
有人知道这是否可能吗?如果是的话,怎么办?
这是我正在使用的(简化的)代码:
struct TextEditorView: UIViewRepresentable {
@Binding var text: NSAttributedString
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> UITextView {
let textEditorView = UITextView()
textEditorView.addToolbar()
textEditorView.allowsEditingTextAttributes = true
textEditorView.delegate = context.coordinator
return textEditorView
}
func updateUIView(_ uiView: UITextView, context: Context) {
uiView.attributedText = text
}
class Coordinator: NSObject, UITextViewDelegate {
var parent: TextEditorView
init(_ uiTextView: TextEditorView) {
self.parent = uiTextView
}
func textViewDidChange(_ textView: UITextView) {
self.parent.text = textView.attributedText
}
}
}
extension UITextView {
func addToolbar() {
let toolbar = UIToolbar()
let formatButton = UIBarButtonItem(
image: UIImage(systemName: "textformat.alt"),
style: .plain,
target: self,
action: #selector(showTextFormattingPanel)
)
toolbar.items = [formatButton]
self.inputAccessoryView = toolbar
}
@objc private func showTextFormattingPanel() {
// ? Show Format Panel ?
}
}
没有公共 API 用于触发
UITextView
的新格式化屏幕的显示。当您在 UITextView
中选择新的格式 -> 更多... 上下文菜单时,会调用私有 API _showTextFormattingOptions:
。所以一种解决方案是直接调用该私有 API:
@objc private func showTextFormattingPanel() {
// Show Format Panel
self.perform(NSSelectorFromString("_showTextFormattingOptions:"), with: self)
}
这在测试开发应用程序中确实有效。但这远非理想。这很可能会导致应用程序因使用私有 API 而被拒绝。尽管选择器字符串会有些混乱,但很容易避免这种情况。更大的问题是,私有 API 可能会在未来的 iOS 更新中发生更改,这将导致应用程序因调用无法识别的选择器而崩溃。
一个更困难的解决方案是创建并呈现您自己的
UITextFormattingViewController
实例。您需要提供一个委托来处理所有值更改,然后需要手动将它们应用到文本视图。这个解决方案需要做更多的工作。它还复制了 UITextView
的私有 API 提供的所有内置功能。而且 UITextFormattingViewController
文档不包含任何注释,因此很难知道有多少 API 可以工作。