Я пишу всплывающее окно настроек для расширения приложения Safari. Он состоит из табличного представления с сегментированным элементом управления, содержащим шаблоны Add, Remove и Action. Последний показывает меню с элементами для импорта и экспорта настроек.
Импорт осуществляется через NSOpenPanel
, к которому я добавил вспомогательное представление с флажком для замены существующих настроек вместо добавления к ним.
Проблема в том, что при выборе пункта меню вспомогательный вид оказывается позади модального NSOpenPanel
, вызывая следующие действия.
- На экране кратко появляется
NSView
перед NSOpenPanel
, NSOpenPanel
показывает пустое пространство (правильного размера), где должно быть вспомогательное представление, и - Если вы нажмете на другое приложение (или рабочий стол), чтобы поставить Safari, уходит в фон, тогда вспомогательное представление появляется в
NSOpenPanel
, за исключением - Если другое приложение перекрывает
NSOpenPanel
, то над этим приложением появляется NSView
, и вы можете нажать на флажок, чтобы изменить его, затем - При нажатии на Safari, чтобы сделать его впереди,
NSView
снова исчезает, однако - Нажатие кнопки Параметры n дважды из
NSOpenPanel
, чтобы закрыть вспомогательный вид, а затем снова открыть, чтобы устранить проблему.
Я добавил цвет фона к NSView
, чтобы убедиться, что проблема именно с этим, а не с приложением NSButton
.
Чтобы убедиться, что мой код был верным, я создал новый проект приложения с помощью всего одной кнопки в его представлении, а затем скопировал мой код в его окно действий. Он работал правильно.
Затем я создал новый проект расширения приложения Safari, сделал то же самое с его поповером и столкнулся с той же проблемой. Я также попытался переместить код за пределы контроллера представления для поповера, но это не имело никакого значения. Так что, похоже, проблема связана с тем, что он вызывается из расширения приложения Safari.
Кроме того, я предполагаю, что это связанная проблема, иногда, когда закрывается NSOpenPanel
(либо путем выбора файла, либо отмены). это) управление не передается обратно в главное окно Safari. Это просто перестает отвечать. Вы можете перемещать окно по экрану, но само приложение, в том числе строка меню, не будет реагировать ни на какие действия мыши или клавиатуры. Единственный вариант - принудительно выйти из него. Однако это также влияет на NSSavePanel
для экспорта, который не имеет дополнительного представления.
Я использую Xcode 11.3 на macOS 10.14.6 для Safari 13.0.4. Это код:
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.allowsOtherFileTypes
игнорируется, но по крайней мере это постоянно не работает в тесте автономного приложения!)
Кто-нибудь может объяснить это? Я действительно хочу иметь настройки в Safari, а не использовать приложение для управления ими.