Swift Safari应用程序扩展中奇怪的NSOpenPanel附件视图行为
我正在为Safari应用程序扩展编写一个设置弹出窗口。这包括一个表视图,其下面有一个分段控件,其中包含添加、删除和操作模板。后者显示一个菜单,其中包含要导入和导出设置的项 导入是通过Swift Safari应用程序扩展中奇怪的NSOpenPanel附件视图行为,swift,nsopenpanel,accessoryview,safari-app-extension,Swift,Nsopenpanel,Accessoryview,Safari App Extension,我正在为Safari应用程序扩展编写一个设置弹出窗口。这包括一个表视图,其下面有一个分段控件,其中包含添加、删除和操作模板。后者显示一个菜单,其中包含要导入和导出设置的项 导入是通过NSOpenPanel进行的,我在其中添加了一个带有复选框的附件视图,以替换现有设置,而不是添加到其中 问题是,当选择菜单项时,附件视图似乎位于modalNSOpenPanel后面,从而导致以下行为 NSView会在NSOpenPanel之前短暂出现在屏幕上,然后 NSOpenPanel显示附件视图应位于的空白区域
NSOpenPanel
进行的,我在其中添加了一个带有复选框的附件视图,以替换现有设置,而不是添加到其中
问题是,当选择菜单项时,附件视图似乎位于modalNSOpenPanel
后面,从而导致以下行为
会在NSView
之前短暂出现在屏幕上,然后NSOpenPanel
显示附件视图应位于的空白区域(大小正确),以及NSOpenPanel
- 如果单击另一个应用程序(或桌面)将Safari置于后台,则附件视图确实会出现在
中,除了NSOpenPanel
- 如果另一个应用程序与
重叠,则该应用程序上方会出现NSOpenPanel
,您可以单击复选框进行更改,然后NSView
- 但是,单击Safari使其成为最前面的
再次消失NSView
- 单击
的选项按钮两次,关闭附件视图,然后重新打开,解决了该问题NSOpenPanel
NSView
中添加了背景色,以确认问题在于此,而不是附带的NSButton
为了验证我的代码是否正确,我创建了一个新的应用程序项目,在它的视图上只有一个按钮,然后将我的代码复制到它的action outlet中。它工作正常
然后我创建了一个新的Safari应用程序扩展项目,在其popover上也做了同样的工作,并遇到了同样的问题。我还尝试将代码移到popover的视图控制器之外,但这没有什么区别。因此,问题似乎与从Safari应用程序扩展中调用有关
此外,我认为这是一个相关的问题,有时当关闭NSOpenPanel
时(无论是选择文件还是取消文件),控件都不会传递回Safari主窗口。它只是变得毫无反应。您可以在屏幕上移动窗口,但应用程序本身(包括菜单栏)不会响应任何鼠标或键盘输入。唯一的选择是强制退出。但是,这也会影响导出时没有附件视图的NSSavePanel
我在macOS 10.14.6上为Safari 13.0.4使用Xcode 11.3。代码如下:
var overwriteSettings: Bool = false
@objc func importSettingsCheckBox(_ button: NSButton) {
self.overwriteSettings = button.state == .on
}
@IBAction func importSettings(_ sender: Any) {
let openFileDialog = NSOpenPanel()
openFileDialog.title = "Choose a settings file…"
openFileDialog.directoryURL = FileManager.default.homeDirectoryForCurrentUser
// openFileDialog.allowedFileTypes = ["json"]
// openFileDialog.allowsOtherFileTypes = true
let dialogWidth = openFileDialog.frame.width
let overwriteSettingsButton = NSButton()
overwriteSettingsButton.setButtonType(.switch)
overwriteSettingsButton.title = "Remove existing settings on import?"
overwriteSettingsButton.target = self
overwriteSettingsButton.action = #selector(importSettingsCheckBox(_:))
overwriteSettingsButton.sizeToFit()
let dialogWidth = openFileDialog.frame.width
let buttonHeight = overwriteSettingsButton.frame.height
overwriteSettingsButton.setFrameOrigin(NSMakePoint((dialogWidth - overwriteSettingsButton.frame.width) / 2, buttonHeight / 2))
let accessoryView = NSView(frame: NSMakeRect(0, 0, dialogWidth, buttonHeight * 2))
accessoryView.autoresizesSubviews = true
accessoryView.addSubview(overwriteSettingsButton)
openFileDialog.accessoryView = accessoryView
openFileDialog.isAccessoryViewDisclosed = true
if openFileDialog.runModal() == NSApplication.ModalResponse.OK {
if let result = openFileDialog.url {
NSLog("I want to open \(result.path), overwrite status: \(self.overwriteSettings)")
}
} else {
NSLog("No file selected")
}
return
}
(注释掉的行是因为被忽略了NSOpenPanel.allowOtherFileTypes
,但至少在独立应用程序测试中一直不起作用!)
有人能解释一下吗?我真的希望在Safari中设置,而不是使用包含它们的应用程序来管理它们