如何为Mac创建Cocoa App首选项?

Cri*_*ian 13 macos cocoa objective-c

我在Xcode for Mac中创建了一个简单的应用程序,它可以构建和编译.

如何为首选项创建菜单?有简单的方法还是我必须创建一个新的界面?然后,我如何获取并将值放入这些首选项中?

我确实找到了一个教程,但是它适用于iOS,而且我可以看到,如果您正在为Mac开发,则"设置包"不可用.

编辑:以下链接是完美的:https://developer.apple.com/cocoa/cocoabindings.html

Ver*_*ous 15

这是您想要的文档. 更具体地说,如何提供首选项界面.

无论如何,您必须像创建任何其他窗口一样创建自己的首选项菜单/窗口,并且有一些控件允许修改随后存储在User Defaults字典中的值,这是通常存储用户首选项的位置(a Cocoa Bindings制作的过程非常简单).

否则,手动,你可能想要一个引用,[NSUserDefaults standardUserDefaults]所以你可以-setObject:ForKey:等等.阅读与上面链接的整个文档(包括其他部分)是明智的.

有关如何使用Cocoa绑定与NSUserDefaults存储/检索首选项进行交互的更多信息,请参阅此处的Apple文档.

  • 我们还建议使用以下链接逐步创建面板和必要的绑定:https://developer.apple.com/cocoa/cocoabindings.html (2认同)

Ric*_* H. 6

对于窗口本身,我建议使用RHPreferences框架.

可在GitHub上获得.BSD许可.

它是一个简单易用的首选项窗口控制器,具有多个选项卡,可用于下一个Mac应

它还提供:

  • 在不同大小的选项卡视图之间自动调整大小(带动画)
  • 自定义NSToolbarItem支持
  • 最后使用的选项卡的持久性
  • 支持占位符NSToolbarItems(例如NSToolbarFlexibleSpaceItemIdentifier和NSToolbarShowFontsItemIdentifier)


Vla*_*lad 5

\n

NSTabViewController.TabStyle.toolbar \xe2\x80\x93 自动将任何选项卡添加到 window\xe2\x80\x99s 工具栏的样式。选项卡视图控制器控制 window\xe2\x80\x99s 工具栏,并将其自身设置为工具栏\xe2\x80\x99s 委托。

\n
\n\n

https://developer.apple.com/documentation/appkit/nstabviewcontroller/tabstyle

\n\n

请记住上面的内容,我们可以NSWindowController使用NSWindow.contentViewControllerset to创建NSTabViewController来获取标准 macOS 首选项窗口。

\n\n

这是一个由代码(Swift 4)制作的首选项窗口:

\n\n

文件:PreferencesPageID.swift \xe2\x80\x93 保留首选项页面属性。用于回调。

\n\n
enum PreferencesPageID: Int, CaseIterable {\n\n   case generic, misc\n\n   var image: NSImage? {\n      switch self {\n      case .generic:\n         return NSImage(named: NSImage.folderSmartName)\n      case .misc:\n         return NSImage(named: NSImage.networkName)\n      }\n   }\n\n   var title: String {\n      switch self {\n      case .generic:\n         return "Some"\n      case .misc:\n         return "Other"\n      }\n   }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

文件:PreferencesTabView.swift \xe2\x80\x93 表示首选项页面内容视图。

\n\n
class PreferencesTabView: View {\n\n   let id: PreferencesPageID\n\n   init(id: PreferencesPageID) {\n      self.id = id\n      super.init()\n   }\n\n   required init?(coder decoder: NSCoder) {\n      fatalError()\n   }\n\n   override func setupUI() {\n      switch id {\n      case .generic:\n         backgroundColor = .red\n         setIntrinsicContentSize(CGSize(width: 400, height: 200))\n      case .misc:\n         backgroundColor = .blue\n         setIntrinsicContentSize(CGSize(width: 400, height: 300))\n      }\n   }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

文件:PreferenceItemViewController.swift - 保持首选项页面内容视图的控制器。主要需要满足 macOS SDK 要求。

\n\n
class PreferenceItemViewController: ViewController {\n\n   private let contentView: PreferencesTabView\n\n   override func loadView() {\n      view = contentView\n   }\n\n   init(view: PreferencesTabView) {\n      contentView = view\n      super.init(nibName: nil, bundle: nil)\n   }\n\n   required init?(coder: NSCoder) {\n      fatalError()\n   }    \n\n   override func viewDidLayout() {\n       super.viewDidLayout()\n       preferredContentSize = view.intrinsicContentSize\n   }    \n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

文件:PreferencesViewController.swift \xe2\x80\x93 用作NSWindow.contentViewController.

\n\n
class PreferencesViewController: TabViewController {\n\n   enum Event {\n      case selected(PreferencesPageID)\n   }\n\n   var eventHandler: ((Event) -> Void)?\n\n\n   override func setupUI() {\n      tabStyle = .toolbar // This will "turn" View Controller to standard Preferences window.\n      transitionOptions = .allowUserInteraction\n      canPropagateSelectedChildViewControllerTitle = false\n      let views = [PreferencesTabView(id: .generic), PreferencesTabView(id: .misc)]\n      views.forEach {\n         let item = NSTabViewItem(viewController: PreferenceItemViewController(view: $0))\n         item.label = $0.id.title\n         item.image = $0.id.image\n         addTabViewItem(item)\n      }\n   }\n\n   override func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {\n      super.tabView(tabView, didSelect: tabViewItem)\n      if let view = tabViewItem?.viewController?.view as? PreferencesTabView {\n         eventHandler?(.selected(view.id))\n      }\n   }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

文件:PreferencesWindowController.swift \xe2\x80\x93 首选项窗口控制器。

\n\n
private class PreferencesWindowController: NSWindowController {\n\n   private(set) lazy var viewController = PreferencesViewController()\n\n   init() {\n      let rect = CGRect(x: 400, y: 200, width: 400, height: 300)\n      let window = NSWindow(contentRect: rect, styleMask: [.titled, .closable], backing: .buffered, defer: true)\n      super.init(window: window)\n\n      setupHandlers()\n\n      let frameSize = window.contentRect(forFrameRect: window.frame).size\n      viewController.view.setFrameSize(frameSize)\n      window.contentViewController = viewController\n   }\n\n   required init?(coder: NSCoder) {\n      fatalError()\n   }\n\n   // MARK: - Private\n\n   private func setupHandlers() {\n      viewController.eventHandler = { [weak self] in\n         switch $0 {\n         case .selected(let id):\n            self?.window?.title = "Preferences \xe2\x80\x94 " + id.title\n         }\n      }\n   }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

用法:

\n\n
public class Application: NSApplication {\n\n   private lazy var preferencesController = PreferencesWindowController()\n\n   // Called from code or via IBAction\n   private func showPreferences() {\n      preferencesController.showWindow(nil)\n   }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

首选项屏幕

\n